diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-06-18 11:37:25 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-06-18 11:37:25 +0200 |
commit | 89ea9c8401d9e1b79977c6556b81b2eb4159ef59 (patch) | |
tree | 15e5e4114c08fc39d75ba9da088177c159cac06e | |
parent | 33ef0312f43646ab3dd9ff95430d70d24bc1d701 (diff) |
Move process from build2 to libbutl
-rw-r--r-- | build/b.cxx | 1 | ||||
-rw-r--r-- | build/buildfile | 4 | ||||
-rw-r--r-- | build/cxx/module.cxx | 2 | ||||
-rw-r--r-- | build/cxx/rule.cxx | 2 | ||||
-rw-r--r-- | build/process | 67 | ||||
-rw-r--r-- | build/process.cxx | 326 |
6 files changed, 4 insertions, 398 deletions
diff --git a/build/b.cxx b/build/b.cxx index d65a6c2..24f4266 100644 --- a/build/b.cxx +++ b/build/b.cxx @@ -27,7 +27,6 @@ #include <build/file> #include <build/module> #include <build/algorithm> -#include <build/process> #include <build/diagnostics> #include <build/context> #include <build/utility> diff --git a/build/buildfile b/build/buildfile index 7d3a32a..8b4cb84 100644 --- a/build/buildfile +++ b/build/buildfile @@ -5,8 +5,8 @@ bin = bin/{target rule module} cxx = cxx/{target rule module} exe{b}: cxx{b algorithm name operation spec scope variable target \ - prerequisite rule file module context search diagnostics token lexer \ - parser process timestamp path path-io utility filesystem dump options \ + prerequisite rule file module context search diagnostics token \ + lexer parser timestamp path path-io utility filesystem dump options \ $config $bin $cxx} $libs #@@ TODO diff --git a/build/cxx/module.cxx b/build/cxx/module.cxx index 6efc1ed..4193104 100644 --- a/build/cxx/module.cxx +++ b/build/cxx/module.cxx @@ -4,11 +4,11 @@ #include <build/cxx/module> +#include <butl/process> #include <butl/fdstream> #include <build/path> #include <build/scope> -#include <build/process> #include <build/diagnostics> #include <build/bin/module> diff --git a/build/cxx/rule.cxx b/build/cxx/rule.cxx index 4fce59a..f05370d 100644 --- a/build/cxx/rule.cxx +++ b/build/cxx/rule.cxx @@ -10,12 +10,12 @@ #include <cstdlib> // exit #include <utility> // move() +#include <butl/process> #include <butl/fdstream> #include <build/scope> #include <build/variable> #include <build/algorithm> -#include <build/process> #include <build/timestamp> #include <build/diagnostics> #include <build/context> diff --git a/build/process b/build/process deleted file mode 100644 index 0e1a8c9..0000000 --- a/build/process +++ /dev/null @@ -1,67 +0,0 @@ -// file : build/process -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUILD_PROCESS -#define BUILD_PROCESS - -#ifndef _WIN32 -# include <sys/types.h> // pid_t -#endif - -#include <cassert> -#include <system_error> - -namespace build -{ - - struct process_error: std::system_error - { - process_error (int e, bool child) - : system_error (e, std::system_category ()), child_ (child) {} - - bool - child () const {return child_;} - - private: - bool child_; - }; - - struct process - { - // Start another process using the specified command line. Connect the - // newly created process' stdin to out_fd. Also if connect_* are true, - // connect the created process' stdout and stderr to in_*fd. Throw - // process_error if anything goes wrong. - // - // Note that some of the exceptions (e.g., if exec() failed) can be - // thrown in the child version of us. - // - process (char const* args[], - bool connect_stdin = false, - bool connect_stderr = false, - bool connect_stdout = false); - - // Wait for the process to terminate. Return true if the process - // terminated normally and with the zero exit status. Throw - // process_error if anything goes wrong. - // - bool - wait (); - - ~process () {assert (id == 0);} - -#ifndef _WIN32 - typedef pid_t id_type; -#else - typedef void* id_type; // Win32 HANDLE. -#endif - - id_type id; - int out_fd; // Write to this fd to send to the new process' stdin. - int in_efd; // Read from this fd to receive from the new process' stderr. - int in_ofd; // Read from this fd to receive from the new process' stdout. - }; -} - -#endif // BUILD_PROCESS diff --git a/build/process.cxx b/build/process.cxx deleted file mode 100644 index 53e66c3..0000000 --- a/build/process.cxx +++ /dev/null @@ -1,326 +0,0 @@ -// file : build/process.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <build/process> - -#ifndef _WIN32 -# include <unistd.h> // execvp, fork, dup2, pipe, {STDIN,STDERR}_FILENO -# include <sys/wait.h> // waitpid -#else -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include <windows.h> // CreatePipe, CreateProcess -# include <io.h> // _open_osfhandle -# include <fcntl.h> // _O_TEXT -#endif - -using namespace std; - -namespace build -{ -#ifndef _WIN32 - - process:: - process (char const* args[], bool in, bool err, bool out) - { - int out_fd[2]; - int in_efd[2]; - int in_ofd[2]; - - if ((in && pipe (out_fd) == -1) || - (err && pipe (in_efd) == -1) || - (out && pipe (in_ofd) == -1)) - throw process_error (errno, false); - - id = fork (); - - if (id == -1) - throw process_error (errno, false); - - if (id == 0) - { - // Child. If requested, close the write end of the pipe and duplicate - // the read end to stdin. Then close the original read end descriptor. - // - if (in) - { - if (close (out_fd[1]) == -1 || - dup2 (out_fd[0], STDIN_FILENO) == -1 || - close (out_fd[0]) == -1) - throw process_error (errno, true); - } - - // Do the same for the stderr if requested. - // - if (err) - { - if (close (in_efd[0]) == -1 || - dup2 (in_efd[1], STDERR_FILENO) == -1 || - close (in_efd[1]) == -1) - throw process_error (errno, true); - } - - // Do the same for the stdout if requested. - // - if (out) - { - if (close (in_ofd[0]) == -1 || - dup2 (in_ofd[1], STDOUT_FILENO) == -1 || - close (in_ofd[1]) == -1) - throw process_error (errno, true); - } - - if (execvp (args[0], const_cast<char**> (&args[0])) == -1) - throw process_error (errno, true); - } - else - { - // Parent. Close the other ends of the pipes. - // - if ((in && close (out_fd[0]) == -1) || - (err && close (in_efd[1]) == -1) || - (out && close (in_ofd[1]) == -1)) - throw process_error (errno, false); - } - - this->out_fd = in ? out_fd[1] : 0; - this->in_efd = err ? in_efd[0] : 0; - this->in_ofd = out ? in_ofd[0] : 0; - } - - bool process:: - wait () - { - int status; - int r (waitpid (id, &status, 0)); - id = 0; // We have tried. - - if (r == -1) - throw process_error (errno, false); - - return WIFEXITED (status) && WEXITSTATUS (status) == 0; - } - -#else // _WIN32 - - static void - print_error (char const* name) - { - LPTSTR msg; - DWORD e (GetLastError()); - - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - 0, - e, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &msg, - 0, - 0)) - { - cerr << name << ": error: unknown error code " << e << endl; - return; - } - - cerr << name << ": error: " << msg << endl; - LocalFree (msg); - } - - static process_info - start_process (char const* args[], char const* name, bool err, bool out) - { - HANDLE out_h[2]; - HANDLE in_eh[2]; - HANDLE in_oh[2]; - SECURITY_ATTRIBUTES sa; - - sa.nLength = sizeof (SECURITY_ATTRIBUTES); - sa.bInheritHandle = true; - sa.lpSecurityDescriptor = 0; - - if (!CreatePipe (&out_h[0], &out_h[1], &sa, 0) || - !SetHandleInformation (out_h[1], HANDLE_FLAG_INHERIT, 0)) - { - print_error (name); - throw process_failure (); - } - - if (err) - { - if (!CreatePipe (&in_eh[0], &in_eh[1], &sa, 0) || - !SetHandleInformation (in_eh[0], HANDLE_FLAG_INHERIT, 0)) - { - print_error (name); - throw process_failure (); - } - } - - if (out) - { - if (!CreatePipe (&in_oh[0], &in_oh[1], &sa, 0) || - !SetHandleInformation (in_oh[0], HANDLE_FLAG_INHERIT, 0)) - { - print_error (name); - throw process_failure (); - } - } - - // Create the process. - // - path file (args[0]); - - // Do PATH search. - // - if (file.directory ().empty ()) - file = path_search (file); - - if (file.empty ()) - { - cerr << args[0] << ": error: file not found" << endl; - throw process_failure (); - } - - // Serialize the arguments to string. - // - string cmd_line; - - for (char const** p (args); *p != 0; ++p) - { - if (p != args) - cmd_line += ' '; - - // On Windows we need to protect values with spaces using quotes. - // Since there could be actual quotes in the value, we need to - // escape them. - // - string a (*p); - bool quote (a.find (' ') != string::npos); - - if (quote) - cmd_line += '"'; - - for (size_t i (0); i < a.size (); ++i) - { - if (a[i] == '"') - cmd_line += "\\\""; - else - cmd_line += a[i]; - } - - if (quote) - cmd_line += '"'; - } - - // Prepare other info. - // - STARTUPINFO si; - PROCESS_INFORMATION pi; - - memset (&si, 0, sizeof (STARTUPINFO)); - memset (&pi, 0, sizeof (PROCESS_INFORMATION)); - - si.cb = sizeof(STARTUPINFO); - - if (err) - si.hStdError = in_eh[1]; - else - si.hStdError = GetStdHandle (STD_ERROR_HANDLE); - - if (out) - si.hStdOutput = in_oh[1]; - else - si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE); - - si.hStdInput = out_h[0]; - si.dwFlags |= STARTF_USESTDHANDLES; - - if (!CreateProcess ( - file.string ().c_str (), - const_cast<char*> (cmd_line.c_str ()), - 0, // Process security attributes. - 0, // Primary thread security attributes. - true, // Inherit handles. - 0, // Creation flags. - 0, // Use our environment. - 0, // Use our current directory. - &si, - &pi)) - { - print_error (name); - throw process_failure (); - } - - CloseHandle (pi.hThread); - CloseHandle (out_h[0]); - - if (err) - CloseHandle (in_eh[1]); - - if (out) - CloseHandle (in_oh[1]); - - process_info r; - r.id = pi.hProcess; - r.out_fd = _open_osfhandle ((intptr_t) (out_h[1]), 0); - - if (r.out_fd == -1) - { - cerr << name << ": error: unable to obtain C file handle" << endl; - throw process_failure (); - } - - if (err) - { - // Pass _O_TEXT to get newline translation. - // - r.in_efd = _open_osfhandle ((intptr_t) (in_eh[0]), _O_TEXT); - - if (r.in_efd == -1) - { - cerr << name << ": error: unable to obtain C file handle" << endl; - throw process_failure (); - } - } - else - r.in_efd = 0; - - if (out) - { - // Pass _O_TEXT to get newline translation. - // - r.in_ofd = _open_osfhandle ((intptr_t) (in_oh[0]), _O_TEXT); - - if (r.in_ofd == -1) - { - cerr << name << ": error: unable to obtain C file handle" << endl; - throw process_failure (); - } - } - else - r.in_ofd = 0; - - return r; - } - - static bool - wait_process (process_info pi, char const* name) - { - DWORD status; - - if (WaitForSingleObject (pi.id, INFINITE) != WAIT_OBJECT_0 || - !GetExitCodeProcess (pi.id, &status)) - { - print_error (name); - throw process_failure (); - } - - CloseHandle (pi.id); - return status == 0; - } - -#endif // _WIN32 -} |