killall.c revision 6301a98cdf26dc073f5317506c806bfa69f74cc8
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog/***
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog This file is part of systemd.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Copyright 2010 ProFUSION embedded systems
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog systemd is free software; you can redistribute it and/or modify it
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog under the terms of the GNU Lesser General Public License as published by
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog the Free Software Foundation; either version 2.1 of the License, or
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog (at your option) any later version.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog systemd is distributed in the hope that it will be useful, but
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog WITHOUT ANY WARRANTY; without even the implied warranty of
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Lesser General Public License for more details.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog You should have received a copy of the GNU Lesser General Public License
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog along with systemd; If not, see <http://www.gnu.org/licenses/>.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog***/
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include <sys/wait.h>
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include <signal.h>
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include <errno.h>
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include <unistd.h>
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include "util.h"
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include "def.h"
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include "killall.h"
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#include "set.h"
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog#define TIMEOUT_USEC (10 * USEC_PER_SEC)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogstatic bool ignore_proc(pid_t pid) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog _cleanup_fclose_ FILE *f = NULL;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog char c, *p;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog size_t count;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog uid_t uid;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog int r;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* We are PID 1, let's not commit suicide */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (pid == 1)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return true;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog r = get_process_uid(pid, &uid);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (r < 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return true; /* not really, but better safe than sorry */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Non-root processes otherwise are always subject to be killed */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (uid != 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return false;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog p = procfs_file_alloca(pid, "cmdline");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog f = fopen(p, "re");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (!f)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return true; /* not really, but has the desired effect */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog count = fread(&c, 1, 1, f);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Kernel threads have an empty cmdline */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (count <= 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return true;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Processes with argv[0][0] = '@' we ignore from the killing
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * spree.
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog *
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (count == 1 && c == '@')
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return true;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return false;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog}
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogstatic void wait_for_children(Set *pids, sigset_t *mask) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog usec_t until;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog assert(mask);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (set_isempty(pids))
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog for (;;) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog struct timespec ts;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog int k;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog usec_t n;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog void *p;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Iterator i;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* First, let the kernel inform us about killed
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * children. Most processes will probably be our
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * children, but some are not (might be our
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * grandchildren instead...). */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog for (;;) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog pid_t pid;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog pid = waitpid(-1, NULL, WNOHANG);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (pid == 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog break;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (pid < 0) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (errno == ECHILD)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog break;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_error("waitpid() failed: %m");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog set_remove(pids, ULONG_TO_PTR(pid));
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Now explicitly check who might be remaining, who
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * might not be our child. */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog SET_FOREACH(p, pids, i) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* We misuse getpgid as a check whether a
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog * process still exists. */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (getpgid((pid_t) PTR_TO_ULONG(p)) >= 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog continue;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (errno != ESRCH)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog continue;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog set_remove(pids, p);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (set_isempty(pids))
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog n = now(CLOCK_MONOTONIC);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (n >= until)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog timespec_store(&ts, until - n);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog k = sigtimedwait(mask, NULL, &ts);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (k != SIGCHLD) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (k < 0 && errno != EAGAIN) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_error("sigtimedwait() failed: %m");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (k >= 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("sigtimedwait() returned unexpected signal.");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog}
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogstatic int killall(int sig, Set *pids, bool send_sighup) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog _cleanup_closedir_ DIR *dir = NULL;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog struct dirent *d;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog dir = opendir("/proc");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (!dir)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return -errno;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog while ((d = readdir(dir))) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog pid_t pid;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (d->d_type != DT_DIR &&
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog d->d_type != DT_UNKNOWN)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog continue;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (parse_pid(d->d_name, &pid) < 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog continue;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (ignore_proc(pid))
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog continue;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (sig == SIGKILL) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog _cleanup_free_ char *s;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog get_process_comm(pid, &s);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_notice("Sending SIGKILL to PID %lu (%s).", (unsigned long) pid, strna(s));
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (kill(pid, sig) >= 0) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (pids)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog set_put(pids, ULONG_TO_PTR((unsigned long) pid));
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog } else if (errno != ENOENT)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("Could not kill %d: %m", pid);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (send_sighup) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog /* Optionally, also send a SIGHUP signal, but
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog only if the process has a controlling
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog tty. This is useful to allow handling of
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog shells which ignore SIGTERM but react to
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog SIGHUP. We do not send this to processes that
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog have no controlling TTY since we don't want to
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog trigger reloads of daemon processes. Also we
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog make sure to only send this after SIGTERM so
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog that SIGTERM is always first in the queue. */
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (get_ctty_devnr(pid, NULL) >= 0)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog kill(pid, SIGHUP);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog }
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog return set_size(pids);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog}
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskogvoid broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) {
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog sigset_t mask, oldmask;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog Set *pids = NULL;
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (wait_for_exit)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog pids = set_new(trivial_hash_func, trivial_compare_func);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog assert_se(sigemptyset(&mask) == 0);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog assert_se(sigaddset(&mask, SIGCHLD) == 0);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("kill(-1, SIGSTOP) failed: %m");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog killall(sig, pids, send_sighup);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog log_warning("kill(-1, SIGCONT) failed: %m");
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog if (wait_for_exit)
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog wait_for_children(pids, &mask);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
d9bf4f8c6c47b8620ffa1a056208eb15118b78d5Umut Tezduyar Lindskog
set_free(pids);
}