Home | History | Annotate | Line # | Download | only in process
      1 // Copyright 2010 Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 // * Redistributions of source code must retain the above copyright
      9 //   notice, this list of conditions and the following disclaimer.
     10 // * Redistributions in binary form must reproduce the above copyright
     11 //   notice, this list of conditions and the following disclaimer in the
     12 //   documentation and/or other materials provided with the distribution.
     13 // * Neither the name of Google Inc. nor the names of its contributors
     14 //   may be used to endorse or promote products derived from this software
     15 //   without specific prior written permission.
     16 //
     17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 #include "utils/process/child.ipp"
     30 
     31 extern "C" {
     32 #include <sys/stat.h>
     33 #include <sys/wait.h>
     34 
     35 #include <fcntl.h>
     36 #include <signal.h>
     37 #include <unistd.h>
     38 }
     39 
     40 #include <cassert>
     41 #include <cerrno>
     42 #include <cstdlib>
     43 #include <cstring>
     44 #include <iostream>
     45 #include <memory>
     46 
     47 #include "utils/defs.hpp"
     48 #include "utils/format/macros.hpp"
     49 #include "utils/logging/macros.hpp"
     50 #include "utils/process/exceptions.hpp"
     51 #include "utils/process/fdstream.hpp"
     52 #include "utils/process/system.hpp"
     53 #include "utils/process/status.hpp"
     54 #include "utils/sanity.hpp"
     55 #include "utils/signals/interrupts.hpp"
     56 
     57 
     58 namespace utils {
     59 namespace process {
     60 
     61 
     62 /// Private implementation fields for child objects.
     63 struct child::impl {
     64     /// The process identifier.
     65     pid_t _pid;
     66 
     67     /// The input stream for the process' stdout and stderr.  May be NULL.
     68     std::unique_ptr< process::ifdstream > _output;
     69 
     70     /// Initializes private implementation data.
     71     ///
     72     /// \param pid The process identifier.
     73     /// \param output The input stream.  Grabs ownership of the pointer.
     74     impl(const pid_t pid, process::ifdstream* output) :
     75         _pid(pid), _output(output) {}
     76 };
     77 
     78 
     79 }  // namespace process
     80 }  // namespace utils
     81 
     82 
     83 namespace fs = utils::fs;
     84 namespace process = utils::process;
     85 namespace signals = utils::signals;
     86 
     87 
     88 namespace {
     89 
     90 
     91 /// Exception-based version of dup(2).
     92 ///
     93 /// \param old_fd The file descriptor to duplicate.
     94 /// \param new_fd The file descriptor to use as the duplicate.  This is
     95 ///     closed if it was open before the copy happens.
     96 ///
     97 /// \throw process::system_error If the call to dup2(2) fails.
     98 static void
     99 safe_dup(const int old_fd, const int new_fd)
    100 {
    101     if (process::detail::syscall_dup2(old_fd, new_fd) == -1) {
    102         const int original_errno = errno;
    103         throw process::system_error(F("dup2(%s, %s) failed") % old_fd % new_fd,
    104                                     original_errno);
    105     }
    106 }
    107 
    108 
    109 /// Exception-based version of open(2) to open (or create) a file for append.
    110 ///
    111 /// \param filename The file to open in append mode.
    112 ///
    113 /// \return The file descriptor for the opened or created file.
    114 ///
    115 /// \throw process::system_error If the call to open(2) fails.
    116 static int
    117 open_for_append(const fs::path& filename)
    118 {
    119     const int fd = process::detail::syscall_open(
    120         filename.c_str(), O_CREAT | O_WRONLY | O_APPEND,
    121         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    122     if (fd == -1) {
    123         const int original_errno = errno;
    124         throw process::system_error(F("Failed to create %s because open(2) "
    125                                       "failed") % filename, original_errno);
    126     }
    127     return fd;
    128 }
    129 
    130 
    131 /// Exception-based, type-improved version of wait(2).
    132 ///
    133 /// Because we are waiting for the termination of a process, and because this is
    134 /// the canonical way to call wait(2) for this module, we ensure from here that
    135 /// any subprocess of the process we are killing is terminated.
    136 ///
    137 /// \param pid The identifier of the process to wait for.
    138 ///
    139 /// \return The termination status of the process.
    140 ///
    141 /// \throw process::system_error If the call to waitpid(2) fails.
    142 static process::status
    143 safe_wait(const pid_t pid)
    144 {
    145     LD(F("Waiting for pid=%s") % pid);
    146     int stat_loc;
    147     if (process::detail::syscall_waitpid(pid, &stat_loc, 0) == -1) {
    148         const int original_errno = errno;
    149         throw process::system_error(F("Failed to wait for PID %s") % pid,
    150                                     original_errno);
    151     }
    152     return process::status(pid, stat_loc);
    153 }
    154 
    155 
    156 /// Logs the execution of another program.
    157 ///
    158 /// \param program The binary to execute.
    159 /// \param args The arguments to pass to the binary, without the program name.
    160 static void
    161 log_exec(const fs::path& program, const process::args_vector& args)
    162 {
    163     std::string plain_command = program.str();
    164     for (process::args_vector::const_iterator iter = args.begin();
    165          iter != args.end(); ++iter)
    166         plain_command += F(" %s") % *iter;
    167     LD(F("Executing %s") % plain_command);
    168 }
    169 
    170 
    171 /// Maximum number of arguments supported by cxx_exec.
    172 ///
    173 /// We need this limit to avoid having to allocate dynamic memory in the child
    174 /// process to construct the arguments list, which would have side-effects in
    175 /// the parent's memory if we use vfork().
    176 #define MAX_ARGS 128
    177 
    178 
    179 static void cxx_exec(const fs::path& program, const process::args_vector& args)
    180     throw() UTILS_NORETURN;
    181 
    182 
    183 /// Executes an external binary and replaces the current process.
    184 ///
    185 /// This function must not use any of the logging features, so that the output
    186 /// of the subprocess is not "polluted" by our own messages.
    187 ///
    188 /// This function must also not affect the global state of the current process
    189 /// as otherwise we would not be able to use vfork().  Only state stored in the
    190 /// stack can be touched.
    191 ///
    192 /// \param program The binary to execute.
    193 /// \param args The arguments to pass to the binary, without the program name.
    194 static void
    195 cxx_exec(const fs::path& program, const process::args_vector& args) throw()
    196 {
    197     assert(args.size() < MAX_ARGS);
    198     try {
    199         const char* argv[MAX_ARGS + 1];
    200 
    201         argv[0] = program.c_str();
    202         for (process::args_vector::size_type i = 0; i < args.size(); i++)
    203             argv[1 + i] = args[i].c_str();
    204         argv[1 + args.size()] = NULL;
    205 
    206         const int ret = ::execv(program.c_str(),
    207                                 (char* const*)(unsigned long)(const void*)argv);
    208         const int original_errno = errno;
    209         assert(ret == -1);
    210 
    211         std::cerr << "Failed to execute " << program << ": "
    212                   << std::strerror(original_errno) << "\n";
    213         std::abort();
    214     } catch (const std::runtime_error& error) {
    215         std::cerr << "Failed to execute " << program << ": "
    216                   << error.what() << "\n";
    217         std::abort();
    218     } catch (...) {
    219         std::cerr << "Failed to execute " << program << "; got unexpected "
    220             "exception during exec\n";
    221         std::abort();
    222     }
    223 }
    224 
    225 
    226 }  // anonymous namespace
    227 
    228 
    229 /// Creates a new child.
    230 ///
    231 /// \param implptr A dynamically-allocated impl object with the contents of the
    232 ///     new child.
    233 process::child::child(impl *implptr) :
    234     _pimpl(implptr)
    235 {
    236 }
    237 
    238 
    239 /// Destructor for child.
    240 process::child::~child(void)
    241 {
    242 }
    243 
    244 
    245 /// Helper function for fork().
    246 ///
    247 /// Please note: if you update this function to change the return type or to
    248 /// raise different errors, do not forget to update fork() accordingly.
    249 ///
    250 /// \return In the case of the parent, a new child object returned as a
    251 /// dynamically-allocated object because children classes are unique and thus
    252 /// noncopyable.  In the case of the child, a NULL pointer.
    253 ///
    254 /// \throw process::system_error If the calls to pipe(2) or fork(2) fail.
    255 std::unique_ptr< process::child >
    256 process::child::fork_capture_aux(void)
    257 {
    258     std::cout.flush();
    259     std::cerr.flush();
    260 
    261     int fds[2];
    262     if (detail::syscall_pipe(fds) == -1)
    263         throw process::system_error("pipe(2) failed", errno);
    264 
    265     std::unique_ptr< signals::interrupts_inhibiter > inhibiter(
    266         new signals::interrupts_inhibiter);
    267     pid_t pid = detail::syscall_fork();
    268     if (pid == -1) {
    269         inhibiter.reset(NULL);  // Unblock signals.
    270         ::close(fds[0]);
    271         ::close(fds[1]);
    272         throw process::system_error("fork(2) failed", errno);
    273     } else if (pid == 0) {
    274         inhibiter.reset(NULL);  // Unblock signals.
    275         ::setpgid(::getpid(), ::getpid());
    276 
    277         try {
    278             ::close(fds[0]);
    279             safe_dup(fds[1], STDOUT_FILENO);
    280             safe_dup(fds[1], STDERR_FILENO);
    281             ::close(fds[1]);
    282         } catch (const system_error& e) {
    283             std::cerr << F("Failed to set up subprocess: %s\n") % e.what();
    284             std::abort();
    285         }
    286         return std::unique_ptr< process::child >();
    287     } else {
    288         ::close(fds[1]);
    289         LD(F("Spawned process %s: stdout and stderr inherited") % pid);
    290         signals::add_pid_to_kill(pid);
    291         inhibiter.reset(NULL);  // Unblock signals.
    292         return std::unique_ptr< process::child >(
    293             new process::child(new impl(pid, new process::ifdstream(fds[0]))));
    294     }
    295 }
    296 
    297 
    298 /// Helper function for fork().
    299 ///
    300 /// Please note: if you update this function to change the return type or to
    301 /// raise different errors, do not forget to update fork() accordingly.
    302 ///
    303 /// \param stdout_file The name of the file in which to store the stdout.
    304 ///     If this has the magic value /dev/stdout, then the parent's stdout is
    305 ///     reused without applying any redirection.
    306 /// \param stderr_file The name of the file in which to store the stderr.
    307 ///     If this has the magic value /dev/stderr, then the parent's stderr is
    308 ///     reused without applying any redirection.
    309 ///
    310 /// \return In the case of the parent, a new child object returned as a
    311 /// dynamically-allocated object because children classes are unique and thus
    312 /// noncopyable.  In the case of the child, a NULL pointer.
    313 ///
    314 /// \throw process::system_error If the call to fork(2) fails.
    315 std::unique_ptr< process::child >
    316 process::child::fork_files_aux(const fs::path& stdout_file,
    317                                const fs::path& stderr_file)
    318 {
    319     std::cout.flush();
    320     std::cerr.flush();
    321 
    322     std::unique_ptr< signals::interrupts_inhibiter > inhibiter(
    323         new signals::interrupts_inhibiter);
    324     pid_t pid = detail::syscall_fork();
    325     if (pid == -1) {
    326         inhibiter.reset(NULL);  // Unblock signals.
    327         throw process::system_error("fork(2) failed", errno);
    328     } else if (pid == 0) {
    329         inhibiter.reset(NULL);  // Unblock signals.
    330         ::setpgid(::getpid(), ::getpid());
    331 
    332         try {
    333             if (stdout_file != fs::path("/dev/stdout")) {
    334                 const int stdout_fd = open_for_append(stdout_file);
    335                 safe_dup(stdout_fd, STDOUT_FILENO);
    336                 ::close(stdout_fd);
    337             }
    338             if (stderr_file != fs::path("/dev/stderr")) {
    339                 const int stderr_fd = open_for_append(stderr_file);
    340                 safe_dup(stderr_fd, STDERR_FILENO);
    341                 ::close(stderr_fd);
    342             }
    343         } catch (const system_error& e) {
    344             std::cerr << F("Failed to set up subprocess: %s\n") % e.what();
    345             std::abort();
    346         }
    347         return std::unique_ptr< process::child >();
    348     } else {
    349         LD(F("Spawned process %s: stdout=%s, stderr=%s") % pid % stdout_file %
    350            stderr_file);
    351         signals::add_pid_to_kill(pid);
    352         inhibiter.reset(NULL);  // Unblock signals.
    353         return std::unique_ptr< process::child >(
    354             new process::child(new impl(pid, NULL)));
    355     }
    356 }
    357 
    358 
    359 /// Spawns a new binary and multiplexes and captures its stdout and stderr.
    360 ///
    361 /// If the subprocess cannot be completely set up for any reason, it attempts to
    362 /// dump an error message to its stderr channel and it then calls std::abort().
    363 ///
    364 /// \param program The binary to execute.
    365 /// \param args The arguments to pass to the binary, without the program name.
    366 ///
    367 /// \return A new child object, returned as a dynamically-allocated object
    368 /// because children classes are unique and thus noncopyable.
    369 ///
    370 /// \throw process::system_error If the process cannot be spawned due to a
    371 ///     system call error.
    372 std::unique_ptr< process::child >
    373 process::child::spawn_capture(const fs::path& program, const args_vector& args)
    374 {
    375     std::unique_ptr< child > child = fork_capture_aux();
    376     if (child.get() == NULL)
    377         cxx_exec(program, args);
    378     log_exec(program, args);
    379     return child;
    380 }
    381 
    382 
    383 /// Spawns a new binary and redirects its stdout and stderr to files.
    384 ///
    385 /// If the subprocess cannot be completely set up for any reason, it attempts to
    386 /// dump an error message to its stderr channel and it then calls std::abort().
    387 ///
    388 /// \param program The binary to execute.
    389 /// \param args The arguments to pass to the binary, without the program name.
    390 /// \param stdout_file The name of the file in which to store the stdout.
    391 /// \param stderr_file The name of the file in which to store the stderr.
    392 ///
    393 /// \return A new child object, returned as a dynamically-allocated object
    394 /// because children classes are unique and thus noncopyable.
    395 ///
    396 /// \throw process::system_error If the process cannot be spawned due to a
    397 ///     system call error.
    398 std::unique_ptr< process::child >
    399 process::child::spawn_files(const fs::path& program,
    400                             const args_vector& args,
    401                             const fs::path& stdout_file,
    402                             const fs::path& stderr_file)
    403 {
    404     std::unique_ptr< child > child = fork_files_aux(stdout_file, stderr_file);
    405     if (child.get() == NULL)
    406         cxx_exec(program, args);
    407     log_exec(program, args);
    408     return child;
    409 }
    410 
    411 
    412 /// Returns the process identifier of this child.
    413 ///
    414 /// \return A process identifier.
    415 int
    416 process::child::pid(void) const
    417 {
    418     return _pimpl->_pid;
    419 }
    420 
    421 
    422 /// Gets the input stream corresponding to the stdout and stderr of the child.
    423 ///
    424 /// \pre The child must have been started by fork_capture().
    425 ///
    426 /// \return A reference to the input stream connected to the output of the test
    427 /// case.
    428 std::istream&
    429 process::child::output(void)
    430 {
    431     PRE(_pimpl->_output.get() != NULL);
    432     return *_pimpl->_output;
    433 }
    434 
    435 
    436 /// Blocks to wait for completion.
    437 ///
    438 /// \return The termination status of the child process.
    439 ///
    440 /// \throw process::system_error If the call to waitpid(2) fails.
    441 process::status
    442 process::child::wait(void)
    443 {
    444     const process::status status = safe_wait(_pimpl->_pid);
    445     {
    446         signals::interrupts_inhibiter inhibiter;
    447         signals::remove_pid_to_kill(_pimpl->_pid);
    448     }
    449     return status;
    450 }
    451