diff options
author | philwo <philwo@google.com> | 2017-05-15 22:03:45 +0200 |
---|---|---|
committer | Dmitry Lomov <dslomov@google.com> | 2017-05-15 23:25:32 +0200 |
commit | 926180997a0f296a5a009326aead887279ce0a90 (patch) | |
tree | 621f5bd1df02a35ded91bf014c08ca79efe6e65f | |
parent | baca6e4cb023649920871b74810927d304729e59 (diff) |
Remove process-tools.cc which I forgot to delete during the last rollback.
PiperOrigin-RevId: 156092500
-rw-r--r-- | src/main/tools/process-tools.cc | 280 |
1 files changed, 0 insertions, 280 deletions
diff --git a/src/main/tools/process-tools.cc b/src/main/tools/process-tools.cc deleted file mode 100644 index a51d8516d5..0000000000 --- a/src/main/tools/process-tools.cc +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/main/tools/process-tools.h" - -#include <errno.h> -#include <fcntl.h> -#include <math.h> -#include <signal.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#if defined(__linux__) -#include <sys/prctl.h> -#endif -#if defined(__FreeBSD__) -#include <sys/procctl.h> -#endif -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <string> -#include <vector> - -using std::vector; - -// Drops privileges irrevocably to the real uid / gid by setting the effective -// and saved uid / gid to the real uid / gid. Useful if we happen to have been -// called as a setuid-/setgid-root binary. -void DropPrivileges() { - if (setgid(getgid()) < 0) { - DIE("setgid"); - } - if (setuid(getuid()) < 0) { - DIE("setuid"); - } -} - -void Redirect(const std::string &target_path, int fd) { - if (!target_path.empty() && target_path != "-") { - const int flags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND; - int fd_out = open(target_path.c_str(), flags, 0666); - if (fd_out < 0) { - DIE("open(%s)", target_path.c_str()); - } - // If we were launched with less than 3 fds (stdin, stdout, stderr) open, - // but redirection is still requested via a command-line flag, something is - // wacky and the following code would not do what we intend to do, so let's - // bail. - if (fd_out < 3) { - DIE("open(%s) returned a handle that is reserved for stdin / stdout / " - "stderr", - target_path.c_str()); - } - if (dup2(fd_out, fd) < 0) { - DIE("dup2()"); - } - if (close(fd_out) < 0) { - DIE("close()"); - } - } -} - -void WriteFile(const std::string &filename, const char *fmt, ...) { - FILE *stream = fopen(filename.c_str(), "w"); - if (stream == nullptr) { - DIE("fopen(%s)", filename.c_str()); - } - - va_list ap; - va_start(ap, fmt); - // Use a local variable to make sure we call va_end before DIE() in case this - // returns an error. - int r = vfprintf(stream, fmt, ap); - va_end(ap); - - if (r < 0) { - DIE("vfprintf"); - } - - if (fclose(stream) != 0) { - DIE("fclose(%s)", filename.c_str()); - } -} - -void SetTimeout(double timeout_secs) { - if (timeout_secs <= 0) { - DIE("timeout_secs must be positive"); - } - - double int_val, fraction_val; - fraction_val = modf(timeout_secs, &int_val); - - struct itimerval timer; - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_usec = 0; - timer.it_value.tv_sec = (time_t)int_val, - timer.it_value.tv_usec = (suseconds_t)(fraction_val * 1e6); - - if (setitimer(ITIMER_REAL, &timer, nullptr) < 0) { - DIE("setitimer"); - } -} - -void InstallSignalHandler(int signum, void (*handler)(int)) { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = handler; - if (handler == SIG_IGN || handler == SIG_DFL) { - // No point in blocking signals when using the default handler or ignoring - // the signal. - if (sigemptyset(&sa.sa_mask) < 0) { - DIE("sigemptyset"); - } - } else { - // When using a custom handler, block all signals from firing while the - // handler is running. - if (sigfillset(&sa.sa_mask) < 0) { - DIE("sigfillset"); - } - } - // sigaction may fail for certain reserved signals. Ignore failure in this - // case. - sigaction(signum, &sa, nullptr); -} - -void IgnoreSignal(int signum) { InstallSignalHandler(signum, SIG_IGN); } - -void RestoreSignalHandlersAndMask() { - // Use an empty signal mask for the process (= unblock all signals). - sigset_t empty_set; - if (sigemptyset(&empty_set) < 0) { - DIE("sigemptyset"); - } - if (sigprocmask(SIG_SETMASK, &empty_set, nullptr) < 0) { - DIE("sigprocmask(SIG_SETMASK, <empty set>, nullptr)"); - } - - // Set the default signal handler for all signals. - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - if (sigemptyset(&sa.sa_mask) < 0) { - DIE("sigemptyset"); - } - sa.sa_handler = SIG_DFL; - for (int i = 1; i < NSIG; ++i) { - // Ignore possible errors, because we might not be allowed to set the - // handler for certain signals, but we still want to try. - sigaction(i, &sa, nullptr); - } -} - -void KillMeWhenMyParentDies(int signum) { -#if defined(__linux__) - if (prctl(PR_SET_PDEATHSIG, signum) < 0) { - DIE("prctl"); - } -#endif -} - -void BecomeSubreaper() { -#if defined(__FreeBSD__) - if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, 0) < 0) { - DIE("procctl"); - } -#endif -#if defined(PR_SET_CHILD_SUBREAPER) - // The "child subreaper" feature needs Linux 3.4 or higher. - // TODO(philwo) print a warning when this fails. - prctl(PR_SET_CHILD_SUBREAPER, 1); -#endif -} - -int SpawnCommand(const vector<char *> &args) { - int child_pid = fork(); - if (child_pid < 0) { - DIE("fork"); - } else if (child_pid == 0) { - // Put the child into its own process group. - if (setpgid(0, 0) < 0) { - DIE("setpgid"); - } - - // Try to assign our terminal to the child process. - if (tcsetpgrp(STDIN_FILENO, getpgrp()) < 0 && errno != ENOTTY) { - DIE("tcsetpgrp") - } - - // Unblock all signals, restore default handlers. - RestoreSignalHandlersAndMask(); - - // Force umask to include read and execute for everyone, to make output - // permissions predictable. - umask(022); - - if (execvp(args[0], args.data()) < 0) { - DIE("execvp(%s, %p)", args[0], args.data()); - } - } - return child_pid; -} - -static void KillAllRemainingChildren(int main_child_pid) { - // If the child process we spawned earlier terminated, we want to make - // sure all remaining (grand)children are killed, too. - if (getpid() == 1) { - // If we're PID 1, this is easy. - if (kill(-1, SIGKILL) < 0 && errno != ESRCH) { - DIE("kill"); - } - } else { -#if defined(__FreeBSD__) - // FreeBSD is cool, because it has an API to kill all our descendants in one - // go. - struct procctl_reaper_kill data; - data.rk_sig = SIGKILL; - if (procctl(P_PID, getpid(), PROC_REAP_KILL, &data) < 0 && errno != ESRCH) { - DIE("procctl") - } -#else - // On other operating systems, we have to resort to sending SIGKILL to the - // process group of our child and hope that this kills them all. - // TODO(philwo) - what if a child switched to a different process group - // and we can't kill it like this? Maybe parse /proc/*/stat and filter - // by "their PPID = my PID"? - if (kill(-main_child_pid, SIGKILL) < 0 && errno != ESRCH) { - DIE("kill"); - } -#endif - } -} - -int WaitForChild(int main_child_pid) { - // This will be overwritten by the real exitcode from the child in the loop - // below. In case something goes horribly wrong and that doesn't happen, at - // least exit with a failure. - int exitcode = EXIT_FAILURE; - while (1) { - // Check for zombies to be reaped and exit, if our own child exited. - int status; - pid_t killed_pid = wait(&status); - - if (killed_pid < 0) { - // Our PID1 process got a signal that interrupted the wait() call and that - // was either ignored or forwarded to the child. This is expected and - // fine, just continue waiting. - if (errno == EINTR) { - continue; - } else if (errno == ECHILD) { - // No children left to wait for, we're done here. - break; - } - DIE("waitpid") - } else { - if (killed_pid == main_child_pid) { - KillAllRemainingChildren(main_child_pid); - - if (WIFSIGNALED(status)) { - exitcode = 128 + WTERMSIG(status); - } else { - exitcode = WEXITSTATUS(status); - } - } - } - } - return exitcode; -} |