aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar philwo <philwo@google.com>2017-05-15 22:03:45 +0200
committerGravatar Dmitry Lomov <dslomov@google.com>2017-05-15 23:25:32 +0200
commit926180997a0f296a5a009326aead887279ce0a90 (patch)
tree621f5bd1df02a35ded91bf014c08ca79efe6e65f
parentbaca6e4cb023649920871b74810927d304729e59 (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.cc280
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;
-}