1// Copyright 2014 The Kyua Authors. 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/operations.hpp" 30 31extern "C" { 32#include <sys/types.h> 33#include <sys/wait.h> 34 35#include <signal.h> 36#include <unistd.h> 37} 38 39#include <cerrno> 40#include <cstdlib> 41#include <cstring> 42#include <iostream> 43 44#include "utils/format/macros.hpp" 45#include "utils/fs/path.hpp" 46#include "utils/logging/macros.hpp" 47#include "utils/process/exceptions.hpp" 48#include "utils/process/system.hpp" 49#include "utils/process/status.hpp" 50#include "utils/sanity.hpp" 51#include "utils/signals/interrupts.hpp" 52 53namespace fs = utils::fs; 54namespace process = utils::process; 55namespace signals = utils::signals; 56 57 58/// Maximum number of arguments supported by exec. 59/// 60/// We need this limit to avoid having to allocate dynamic memory in the child 61/// process to construct the arguments list, which would have side-effects in 62/// the parent's memory if we use vfork(). 63#define MAX_ARGS 128 64 65 66namespace { 67 68 69/// Exception-based, type-improved version of wait(2). 70/// 71/// \return The PID of the terminated process and its termination status. 72/// 73/// \throw process::system_error If the call to wait(2) fails. 74static process::status 75safe_wait(void) 76{ 77 LD("Waiting for any child process"); 78 int stat_loc; 79 const pid_t pid = ::wait(&stat_loc); 80 if (pid == -1) { 81 const int original_errno = errno; 82 throw process::system_error("Failed to wait for any child process", 83 original_errno); 84 } 85 return process::status(pid, stat_loc); 86} 87 88 89/// Exception-based, type-improved version of waitpid(2). 90/// 91/// \param pid The identifier of the process to wait for. 92/// 93/// \return The termination status of the process. 94/// 95/// \throw process::system_error If the call to waitpid(2) fails. 96static process::status 97safe_waitpid(const pid_t pid) 98{ 99 LD(F("Waiting for pid=%s") % pid); 100 int stat_loc; 101 if (process::detail::syscall_waitpid(pid, &stat_loc, 0) == -1) { 102 const int original_errno = errno; 103 throw process::system_error(F("Failed to wait for PID %s") % pid, 104 original_errno); 105 } 106 return process::status(pid, stat_loc); 107} 108 109 110} // anonymous namespace 111 112 113/// Executes an external binary and replaces the current process. 114/// 115/// This function must not use any of the logging features so that the output 116/// of the subprocess is not "polluted" by our own messages. 117/// 118/// This function must also not affect the global state of the current process 119/// as otherwise we would not be able to use vfork(). Only state stored in the 120/// stack can be touched. 121/// 122/// \param program The binary to execute. 123/// \param args The arguments to pass to the binary, without the program name. 124void 125process::exec(const fs::path& program, const args_vector& args) throw() 126{ 127 try { 128 exec_unsafe(program, args); 129 } catch (const system_error& error) { 130 // Error message already printed by exec_unsafe. 131 std::abort(); 132 } 133} 134 135 136/// Executes an external binary and replaces the current process. 137/// 138/// This differs from process::exec() in that this function reports errors 139/// caused by the exec(2) system call to let the caller decide how to handle 140/// them. 141/// 142/// This function must not use any of the logging features so that the output 143/// of the subprocess is not "polluted" by our own messages. 144/// 145/// This function must also not affect the global state of the current process 146/// as otherwise we would not be able to use vfork(). Only state stored in the 147/// stack can be touched. 148/// 149/// \param program The binary to execute. 150/// \param args The arguments to pass to the binary, without the program name. 151/// 152/// \throw system_error If the exec(2) call fails. 153void 154process::exec_unsafe(const fs::path& program, const args_vector& args) 155{ 156 PRE(args.size() < MAX_ARGS); 157 int original_errno = 0; 158 try { 159 const char* argv[MAX_ARGS + 1]; 160 161 argv[0] = program.c_str(); 162 for (args_vector::size_type i = 0; i < args.size(); i++) 163 argv[1 + i] = args[i].c_str(); 164 argv[1 + args.size()] = NULL; 165 166 const int ret = ::execv(program.c_str(), 167 (char* const*)(unsigned long)(const void*)argv); 168 original_errno = errno; 169 INV(ret == -1); 170 std::cerr << "Failed to execute " << program << ": " 171 << std::strerror(original_errno) << "\n"; 172 } catch (const std::runtime_error& error) { 173 std::cerr << "Failed to execute " << program << ": " 174 << error.what() << "\n"; 175 std::abort(); 176 } catch (...) { 177 std::cerr << "Failed to execute " << program << "; got unexpected " 178 "exception during exec\n"; 179 std::abort(); 180 } 181 182 // We must do this here to prevent our exception from being caught by the 183 // generic handlers above. 184 INV(original_errno != 0); 185 throw system_error("Failed to execute " + program.str(), original_errno); 186} 187 188 189/// Forcibly kills a process group started by us. 190/// 191/// This function is safe to call from an signal handler context. 192/// 193/// Pretty much all of our subprocesses run in their own process group so that 194/// we can terminate them and thier children should we need to. Because of 195/// this, the very first thing our subprocesses do is create a new process group 196/// for themselves. 197/// 198/// The implication of the above is that simply issuing a killpg() call on the 199/// process group is racy: if the subprocess has not yet had a chance to prepare 200/// its own process group, then we will not be killing anything. To solve this, 201/// we must also kill() the process group leader itself, and we must do so after 202/// the call to killpg(). Doing this is safe because: 1) the process group must 203/// have the same ID as the PID of the process that created it; and 2) we have 204/// not yet issued a wait() call so we still own the PID. 205/// 206/// The sideffect of doing what we do here is that the process group leader may 207/// receive a signal twice. But we don't care because we are forcibly 208/// terminating the process group and none of the processes can controlledly 209/// react to SIGKILL. 210/// 211/// \param pgid PID or process group ID to terminate. 212void 213process::terminate_group(const int pgid) 214{ 215 (void)::killpg(pgid, SIGKILL); 216 (void)::kill(pgid, SIGKILL); 217} 218 219 220/// Terminates the current process reproducing the given status. 221/// 222/// The caller process is abruptly terminated. In particular, no output streams 223/// are flushed, no destructors are called, and no atexit(2) handlers are run. 224/// 225/// \param status The status to "re-deliver" to the caller process. 226void 227process::terminate_self_with(const status& status) 228{ 229 if (status.exited()) { 230 ::_exit(status.exitstatus()); 231 } else { 232 INV(status.signaled()); 233 (void)::kill(::getpid(), status.termsig()); 234 UNREACHABLE_MSG(F("Signal %s terminated %s but did not terminate " 235 "ourselves") % status.termsig() % status.dead_pid()); 236 } 237} 238 239 240/// Blocks to wait for completion of a subprocess. 241/// 242/// \param pid Identifier of the process to wait for. 243/// 244/// \return The termination status of the child process that terminated. 245/// 246/// \throw process::system_error If the call to wait(2) fails. 247process::status 248process::wait(const int pid) 249{ 250 const process::status status = safe_waitpid(pid); 251 { 252 signals::interrupts_inhibiter inhibiter; 253 signals::remove_pid_to_kill(pid); 254 } 255 return status; 256} 257 258 259/// Blocks to wait for completion of any subprocess. 260/// 261/// \return The termination status of the child process that terminated. 262/// 263/// \throw process::system_error If the call to wait(2) fails. 264process::status 265process::wait_any(void) 266{ 267 const process::status status = safe_wait(); 268 { 269 signals::interrupts_inhibiter inhibiter; 270 signals::remove_pid_to_kill(status.dead_pid()); 271 } 272 return status; 273} 274