aboutsummaryrefslogtreecommitdiff
path: root/build/process.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-06-18 11:37:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-06-18 11:37:25 +0200
commit89ea9c8401d9e1b79977c6556b81b2eb4159ef59 (patch)
tree15e5e4114c08fc39d75ba9da088177c159cac06e /build/process.cxx
parent33ef0312f43646ab3dd9ff95430d70d24bc1d701 (diff)
Move process from build2 to libbutl
Diffstat (limited to 'build/process.cxx')
-rw-r--r--build/process.cxx326
1 files changed, 0 insertions, 326 deletions
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
-}