diff options
Diffstat (limited to 'src/main/cpp/blaze_util_linux.cc')
-rw-r--r-- | src/main/cpp/blaze_util_linux.cc | 91 |
1 files changed, 24 insertions, 67 deletions
diff --git a/src/main/cpp/blaze_util_linux.cc b/src/main/cpp/blaze_util_linux.cc index bd5fc852cb..5db5cb538a 100644 --- a/src/main/cpp/blaze_util_linux.cc +++ b/src/main/cpp/blaze_util_linux.cc @@ -20,7 +20,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> // strerror -#include <sys/fcntl.h> #include <sys/socket.h> #include <sys/statfs.h> #include <sys/types.h> @@ -168,71 +167,34 @@ string GetDefaultHostJavabase() { return blaze_util::Dirname(blaze_util::Dirname(javac_dir)); } -// Called from a signal handler. Therefore, we can't use our usual set of -// helper functions for reading files, splitting strings and so on. -static bool GetStartTime(int pid, char* output, int output_len) { - char statfile[128]; - snprintf(statfile, sizeof(statfile), "/proc/%d/stat", pid); - int fd = open(statfile, O_RDONLY); - if (fd < 0) { - return false; - } +// Called from a signal handler! +static bool GetStartTime(const string& pid, string* start_time) { + string statfile = "/proc/" + pid + "/stat"; + string statline; - // Note that this allocates 1K on any random stack the signal handler is - // called on - char statline[1024]; - int statline_len = read(fd, statline, 1024); - close(fd); - if (statline_len < 0) { + if (!ReadFile(statfile, &statline)) { return false; } - // Field 22 is that start time of the process since system startup in jiffies. - int space_count = 0; - int space_21 = -1; - int space_22 = -1; - - for (int i = 0; i < statline_len; i++) { - if (statline[i] == ' ') { - switch (++space_count) { - case 21: - space_21 = i; - break; - - case 22: - space_22 = i; - break; - - default: - // We don't care - break; - } - } - } - - if (space_21 == -1 || space_22 == -1) { - // Invalid statline format + vector<string> stat_entries = blaze_util::Split(statline, ' '); + if (stat_entries.size() < 22) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, - "Format of stat file at %s is unknown", statfile); + "Format of stat file at %s is unknown", statfile.c_str()); } - int jiffies_len = space_22 - space_21 - 1; - if (jiffies_len >= output_len) { - // Not enough space in output buffer (Note that we need one extra byte - // for the terminating NUL!) - return false; - } - - strncpy(output, statline + space_21 + 1, jiffies_len); - output[jiffies_len] = 0; + // Start time since startup in jiffies. This combined with the PID should be + // unique. + *start_time = stat_entries[21]; return true; } void WriteSystemSpecificProcessIdentifier(const string& server_dir) { - char start_time[256]; - if (!GetStartTime(getpid(), start_time, 256)) { + string pid = ToString(getpid()); + + string start_time; + if (!GetStartTime(pid, &start_time)) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, - "Cannot get start time of process %d", getpid()); + "Cannot get start time of process %s", pid.c_str()); } string start_time_file = blaze_util::JoinPath(server_dir, "server.starttime"); @@ -245,13 +207,10 @@ void WriteSystemSpecificProcessIdentifier(const string& server_dir) { // On Linux we use a combination of PID and start time to identify the server // process. That is supposed to be unique unless one can start more processes // than there are PIDs available within a single jiffy. -// -// This looks complicated, but all it does is an open(), then read(), then -// close(), all of which are safe to call from signal handlers. -bool KillServerProcess( +bool VerifyServerProcess( int pid, const string& output_base, const string& install_base) { - char start_time[256]; - if (!GetStartTime(pid, start_time, sizeof(start_time))) { + string start_time; + if (!GetStartTime(ToString(pid), &start_time)) { // Cannot read PID file from /proc . Process died meantime, all is good. No // stale server is present. return false; @@ -262,14 +221,12 @@ bool KillServerProcess( blaze_util::JoinPath(output_base, "server/server.starttime"), &recorded_start_time); - // start time file got deleted, but PID file didn't. This is strange. - // Assume that this is an old Blaze process that doesn't know how to write - // start time files yet. - if (file_present && recorded_start_time != start_time) { - // This is a different process. - return false; - } + // If start time file got deleted, but PID file didn't, assume taht this is an + // old Blaze process that doesn't know how to write start time files yet. + return !file_present || recorded_start_time == start_time; +} +bool KillServerProcess(int pid) { // Kill the process and make sure it's dead before proceeding. killpg(pid, SIGKILL); int check_killed_retries = 10; |