aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/cpp/blaze_util_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/cpp/blaze_util_linux.cc')
-rw-r--r--src/main/cpp/blaze_util_linux.cc91
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;