summaryrefslogtreecommitdiff
path: root/linkers/rld-process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linkers/rld-process.cpp')
-rw-r--r--linkers/rld-process.cpp561
1 files changed, 0 insertions, 561 deletions
diff --git a/linkers/rld-process.cpp b/linkers/rld-process.cpp
deleted file mode 100644
index bfd6734..0000000
--- a/linkers/rld-process.cpp
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright (c) 2011, Chris Johns <chrisj@rtems.org>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "config.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#ifndef WIFEXITED
-#define WIFEXITED(S) (((S) & 0xff) == 0)
-#endif
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
-#endif
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
-#endif
-#ifndef WTERMSIG
-#define WTERMSIG(S) ((S) & 0x7f)
-#endif
-#ifndef WIFSTOPPED
-#define WIFSTOPPED WIFEXITED
-#endif
-#ifndef WSTOPSIG
-#define WSTOPSIG WEXITSTATUS
-#endif
-
-#if __WIN32__
-#define CREATE_MODE (S_IRUSR | S_IWUSR)
-#define OPEN_FLAGS (O_BINARY)
-#else
-#define CREATE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)
-#define OPEN_FLAGS (0)
-#endif
-
-#include <iostream>
-
-#include "rld.h"
-#include "rld-process.h"
-
-#include <libiberty.h>
-
-namespace rld
-{
- namespace process
- {
- /**
- * Global keep of temporary files if true. Used to help debug a system.
- */
- bool keep_temporary_files = false;
-
- /**
- * The temporary files.
- */
- temporary_files temporaries;
-
- temporary_files::temporary_files ()
- {
- }
-
- temporary_files::~temporary_files ()
- {
- clean_up ();
- }
-
- const std::string
- temporary_files::get (const std::string& suffix, bool keep)
- {
- char* temp = ::make_temp_file (suffix.c_str ());
-
- if (!temp)
- throw rld::error ("bad temp name", "temp-file");
-
- const std::string name = rld::find_replace (temp,
- RLD_PATH_SEPARATOR_STR RLD_PATH_SEPARATOR_STR,
- RLD_PATH_SEPARATOR_STR);
- tempfile_ref ref (name, keep);
- tempfiles.push_back (ref);
- return name;
- }
-
- void
- temporary_files::unlink (const tempfile_ref& ref)
- {
- if (!keep_temporary_files && !ref.keep)
- rld::path::unlink (ref.name);
- }
-
- void
- temporary_files::erase (const std::string& name)
- {
- for (tempfile_container::iterator tfi = tempfiles.begin ();
- tfi != tempfiles.end ();
- ++tfi)
- {
- if ((*tfi).name == name)
- {
- unlink (*tfi);
- tempfiles.erase (tfi);
- break;
- }
- }
- }
-
- void
- temporary_files::keep (const std::string& name)
- {
- for (tempfile_container::iterator tfi = tempfiles.begin ();
- tfi != tempfiles.end ();
- ++tfi)
- {
- if ((*tfi).name == name)
- {
- (*tfi).keep = true;
- break;
- }
- }
- }
-
- void
- temporary_files::clean_up ()
- {
- for (tempfile_container::iterator tfi = tempfiles.begin ();
- tfi != tempfiles.end ();
- ++tfi)
- {
- unlink (*tfi);
- }
- }
-
- tempfile::tempfile (const std::string& suffix, bool _keep)
- : suffix (suffix),
- overridden (false),
- fd (-1),
- level (0)
- {
- _name = temporaries.get (suffix, _keep);
- }
-
- tempfile::~tempfile ()
- {
- close ();
- temporaries.erase (_name);
- }
-
- void
- tempfile::open (bool writable)
- {
- if (fd < 0)
- {
- bool ok = rld::path::check_file (_name);
- int flags = writable ? O_RDWR : O_RDONLY;
- int mode = writable ? CREATE_MODE : 0;
-
- if (writable && overridden)
- {
- flags |= O_CREAT | O_TRUNC | O_APPEND;
- }
- else
- {
- if (!ok)
- throw rld::error ("Not found.", "tempfile open:" + _name);
- }
-
- level = 0;
- fd = ::open (_name.c_str (), flags, mode);
- if (fd < 0)
- throw rld::error (::strerror (errno), "tempfile open:" + _name);
- }
- }
-
- void
- tempfile::close ()
- {
- if (fd != -1)
- {
- ::close (fd);
- fd = -1;
- level = 0;
- }
- }
-
- void
- tempfile::override (const std::string& name_)
- {
- if (fd >= 0)
- throw rld::error ("Already open", "tempfile override");
- rld::path::unlink (_name);
- overridden = true;
- _name = name_ + suffix;
- }
-
- void
- tempfile::keep ()
- {
- temporaries.keep (_name);
- }
-
- const std::string&
- tempfile::name () const
- {
- return _name;
- }
-
- size_t
- tempfile::size ()
- {
- if (fd < 0)
- return 0;
-
- struct stat sb;
- if (::stat (_name.c_str (), &sb) == 0)
- return sb.st_size;
-
- return 0;
- }
-
- void
- tempfile::read (std::string& all)
- {
- all.clear ();
- if (fd != -1)
- {
- if (level)
- all.append (buf, level);
- level = 0;
- while (true)
- {
- int read = ::read (fd, buf, sizeof (buf) );
- if (read < 0)
- throw rld::error (::strerror (errno), "tempfile get read:" + _name);
- else if (read == 0)
- break;
- else
- all.append (buf, read);
- }
- }
- }
-
- void
- tempfile::read_line (std::string& line)
- {
- line.clear ();
- if (fd != -1)
- {
- bool reading = true;
- while (reading)
- {
- if (level < (sizeof (buf) - 1))
- {
- memset (buf + level, 0, sizeof (buf) - level);
- int read = ::read (fd, buf + level, sizeof (buf) - level - 1);
- if (read < 0)
- throw rld::error (::strerror (errno), "tempfile read:" + _name);
- else if (read == 0)
- reading = false;
- else
- level += read;
- }
- if (level)
- {
- char* lf = ::strchr (buf, '\n');
- int len = level;
- if (lf)
- len = lf - &buf[0] + 1;
- if (lf || !reading)
- {
- line.append (buf, len);
- level -= len;
- }
- if (level)
- ::memmove (buf, &buf[len], level + 1);
- reading = false;
- }
- }
- }
- }
-
- void
- tempfile::write (const std::string& s)
- {
- const char* p = s.c_str ();
- size_t l = s.length ();
- while (l)
- {
- int written = ::write (fd, p, l);
- if (written < 0)
- throw rld::error (::strerror (errno), "tempfile write:" + _name);
- if (written == 0)
- break;
- l -= written;
- }
- }
-
- void
- tempfile::write_line (const std::string& s)
- {
- write (s);
- write (RLD_LINE_SEPARATOR);
- }
-
- void
- tempfile::write_lines (const rld::strings& ss)
- {
- for (rld::strings::const_iterator ssi = ss.begin ();
- ssi != ss.end ();
- ++ssi)
- {
- write_line (*ssi);
- }
- }
-
- void
- tempfile::output (std::ostream& out)
- {
- std::string prefix;
- output (prefix, out);
- }
-
- void
- tempfile::output (const std::string& prefix,
- std::ostream& out,
- bool line_numbers)
- {
- if (fd == -1)
- {
- std::string line;
- int lc = 0;
- open ();
- while (true)
- {
- read_line (line);
- ++lc;
- if (line.empty ())
- break;
- if (!prefix.empty ())
- out << prefix << ": ";
- if (line_numbers)
- out << lc << ": ";
- out << line << std::flush;
- }
- close ();
- }
- }
-
- void
- set_keep_temporary_files ()
- {
- keep_temporary_files = true;
- }
-
- void
- temporaries_clean_up ()
- {
- temporaries.clean_up ();
- }
-
- void
- args_append (arg_container& args, const std::string& str)
- {
- rld::strings ss;
- rld::split (ss, str);
- for (rld::strings::iterator ssi = ss.begin ();
- ssi != ss.end ();
- ++ssi)
- {
- args.push_back (*ssi);
- }
- }
-
- status
- execute (const std::string& pname,
- const std::string& command,
- const std::string& outname,
- const std::string& errname)
- {
- arg_container args;
- parse_command_line (command, args);
- return execute (pname, args, outname, errname);
- }
-
- status
- execute (const std::string& pname,
- const arg_container& args,
- const std::string& outname,
- const std::string& errname)
- {
- if (rld::verbose (RLD_VERBOSE_TRACE))
- {
- std::cout << "execute: ";
- for (size_t a = 0; a < args.size (); ++a)
- std::cout << args[a] << ' ';
- std::cout << std::endl;
- }
-
- const char** cargs = new const char* [args.size () + 1];
-
- for (size_t a = 0; a < args.size (); ++a)
- cargs[a] = args[a].c_str ();
- cargs[args.size ()] = 0;
-
- int err = 0;
- int s = 0;
-
- const char* serr = pex_one (PEX_LAST | PEX_SEARCH,
- args[0].c_str (),
- (char* const*) cargs,
- pname.c_str (),
- outname.c_str (),
- errname.c_str (),
- &s,
- &err);
-
- delete [] cargs;
-
- if (serr)
- throw rld::error ("execute: " + args[0], serr);
- else if (err)
- throw rld::error ("execute: " + args[0], ::strerror (err));
-
- status _status;
-
- if (rld::verbose (RLD_VERBOSE_TRACE))
- std::cout << "execute: status: ";
-
- if (WIFEXITED (s))
- {
- _status.type = status::normal;
- _status.code = WEXITSTATUS (s);
- if (rld::verbose (RLD_VERBOSE_TRACE))
- std::cout << _status.code << std::endl;
- }
- else if (WIFSIGNALED (s))
- {
- _status.type = status::signal;
- _status.code = WTERMSIG (s);
- if (rld::verbose (RLD_VERBOSE_TRACE))
- std::cout << "signal: " << _status.code << std::endl;
- }
- else if (WIFSTOPPED (s))
- {
- _status.type = status::stopped;
- _status.code = WSTOPSIG (s);
- if (rld::verbose (RLD_VERBOSE_TRACE))
- std::cout << "stopped: " << _status.code << std::endl;
- }
- else
- throw rld::error ("execute: " + args[0], "unknown status returned");
-
- return _status;
- }
-
- /*
- * The code is based on this C file:
- * http://cybertiggyr.com/pcm/src/parse.c
- */
- void
- parse_command_line (const std::string& command, arg_container& args)
- {
- enum pstate
- {
- pstate_discard_space,
- pstate_accumulate_quoted,
- pstate_accumulate_raw
- };
-
- args.clear ();
-
- const char quote = '"';
- const char escape = '\\';
- pstate state = pstate_discard_space;
- size_t start = 0;
- size_t i = 0;
-
- while (i < command.size ())
- {
- switch (state)
- {
- case pstate_discard_space:
- if (command[i] == quote)
- {
- ++i;
- start = i;
- state = pstate_accumulate_quoted;
- }
- else if (::isspace (command[i]))
- {
- ++i;
- }
- else /* includes escape */
- {
- start = i;
- state = pstate_accumulate_raw;
- }
- break;
-
- case pstate_accumulate_quoted:
- if (command[i] == quote)
- {
- args.push_back (command.substr (start, i - 1));
- ++i;
- state = pstate_discard_space;
- }
- else if ((command[i] == escape) && (command[i + 1] == quote))
- {
- i += 2;
- }
- else /* includes space */
- {
- ++i;
- }
- break;
-
- case pstate_accumulate_raw:
- if (command[i] == quote)
- {
- throw rld::error ("quote in token", "command parse");
- }
- else if ((command[i] == escape) && (command[i + 1] == quote))
- {
- i += 2;
- }
- else if (::isspace (command[i]))
- {
- args.push_back (command.substr (start, i - 1));
- ++i;
- state = pstate_discard_space;
- }
- else
- {
- ++i;
- }
- break;
- }
- }
- }
- }
-}