X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshutdown.c;fp=src%2Fshutdown.c;h=46b5aea1c80d940b385db0ccb9264fbfb6881e93;hp=11213f9d595a288c57e3d803d3ed8d21ff16a115;hb=7e4ab3c5a6295193d0c58d353b6430265d842f34;hpb=6bd9fe5a734893262f2932a8e1fcfe05796f0105 diff --git a/src/shutdown.c b/src/shutdown.c index 11213f9d5..46b5aea1c 100644 --- a/src/shutdown.c +++ b/src/shutdown.c @@ -47,29 +47,45 @@ #define FINALIZE_ATTEMPTS 50 static bool ignore_proc(pid_t pid) { + char buf[PATH_MAX]; + FILE *f; + char c; + size_t count; + uid_t uid; + int r; + + /* We are PID 1, let's not commit suicide */ if (pid == 1) return true; - /* TODO: add more ignore rules here: device-mapper, etc */ + r = get_process_uid(pid, &uid); + if (r < 0) + return true; /* not really, but better safe than sorry */ - return false; -} + /* Non-root processes otherwise are always subject to be killed */ + if (uid != 0) + return false; -static bool is_kernel_thread(pid_t pid) -{ - char buf[PATH_MAX]; - FILE *f; - char c; - size_t count; + snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid); + char_array_0(buf); - snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long)pid); f = fopen(buf, "re"); if (!f) return true; /* not really, but has the desired effect */ count = fread(&c, 1, 1, f); fclose(f); - return count != 1; + + /* Kernel threads have an empty cmdline */ + if (count <= 0) + return true; + + /* Processes with argv[0][0] = '@' we ignore from the killing + * spree. */ + if (count == 1 && c == '@') + return true; + + return false; } static int killall(int sign) { @@ -77,7 +93,8 @@ static int killall(int sign) { struct dirent *d; unsigned int n_processes = 0; - if ((dir = opendir("/proc")) == NULL) + dir = opendir("/proc"); + if (!dir) return -errno; while ((d = readdir(dir))) { @@ -86,9 +103,6 @@ static int killall(int sign) { if (parse_pid(d->d_name, &pid) < 0) continue; - if (is_kernel_thread(pid)) - continue; - if (ignore_proc(pid)) continue;