(root)/
util-linux-2.39/
misc-utils/
kill.c
       1  /*
       2   * Copyright (c) 1988, 1993, 1994
       3   *	The Regents of the University of California.  All rights reserved.
       4   *
       5   * Redistribution and use in source and binary forms, with or without
       6   * modification, are permitted provided that the following conditions
       7   * are met:
       8   * 1. Redistributions of source code must retain the above copyright
       9   *    notice, this list of conditions and the following disclaimer.
      10   * 2. Redistributions in binary form must reproduce the above copyright
      11   *    notice, this list of conditions and the following disclaimer in the
      12   *    documentation and/or other materials provided with the distribution.
      13   * 3. All advertising materials mentioning features or use of this software
      14   *    must display the following acknowledgement:
      15   *	This product includes software developed by the University of
      16   *	California, Berkeley and its contributors.
      17   * 4. Neither the name of the University nor the names of its contributors
      18   *    may be used to endorse or promote products derived from this software
      19   *    without specific prior written permission.
      20   *
      21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      25   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31   * SUCH DAMAGE.
      32   */
      33  /*
      34   *  oct 5 1994 -- almost entirely re-written to allow for process names.
      35   *  modifications (c) salvatore valente <svalente@mit.edu>
      36   *  may be used / modified / distributed under the same terms as the original.
      37   *
      38   *  1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
      39   *  - added Native Language Support
      40   *
      41   *  1999-11-13 aeb Accept signal numbers 128+s.
      42   *
      43   * Copyright (C) 2014 Sami Kerola <kerolasa@iki.fi>
      44   * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
      45   */
      46  
      47  #include <ctype.h>		/* for isdigit() */
      48  #include <signal.h>
      49  #include <stdio.h>
      50  #include <stdlib.h>
      51  #include <string.h>
      52  #include <unistd.h>
      53  
      54  #include "c.h"
      55  #include "closestream.h"
      56  #include "nls.h"
      57  #include "pidfd-utils.h"
      58  #include "procfs.h"
      59  #include "pathnames.h"
      60  #include "signames.h"
      61  #include "strutils.h"
      62  #include "ttyutils.h"
      63  #include "xalloc.h"
      64  #include "fileutils.h"
      65  
      66  /* partial success, otherwise we return regular EXIT_{SUCCESS,FAILURE} */
      67  #define KILL_EXIT_SOMEOK	64
      68  
      69  enum {
      70  	KILL_FIELD_WIDTH = 11,
      71  	KILL_OUTPUT_WIDTH = 72
      72  };
      73  
      74  #ifdef UL_HAVE_PIDFD
      75  # include <poll.h>
      76  # include "list.h"
      77  struct timeouts {
      78  	int period;
      79  	int sig;
      80  	struct list_head follow_ups;
      81  };
      82  #endif
      83  
      84  struct kill_control {
      85  	char *arg;
      86  	pid_t pid;
      87  	int numsig;
      88  #ifdef HAVE_SIGQUEUE
      89  	union sigval sigdata;
      90  #endif
      91  #ifdef UL_HAVE_PIDFD
      92  	struct list_head follow_ups;
      93  #endif
      94  	unsigned int
      95  		check_all:1,
      96  		do_kill:1,
      97  		do_pid:1,
      98  		require_handler:1,
      99  		use_sigval:1,
     100  #ifdef UL_HAVE_PIDFD
     101  		timeout:1,
     102  #endif
     103  		verbose:1;
     104  };
     105  
     106  static void print_signal_name(int signum)
     107  {
     108  	const char *name = signum_to_signame(signum);
     109  
     110  	if (name) {
     111  		printf("%s\n", name);
     112  		return;
     113  	}
     114  #ifdef SIGRTMIN
     115  	if (SIGRTMIN <= signum && signum <= SIGRTMAX) {
     116  		printf("RT%d\n", signum - SIGRTMIN);
     117  		return;
     118  	}
     119  #endif
     120  	printf("%d\n", signum);
     121  }
     122  
     123  static void pretty_print_signal(FILE *fp, size_t term_width, size_t *lpos,
     124  				int signum, const char *name)
     125  {
     126  	if (term_width < (*lpos + KILL_FIELD_WIDTH)) {
     127  		fputc('\n', fp);
     128  		*lpos = 0;
     129  	}
     130  	*lpos += KILL_FIELD_WIDTH;
     131  	fprintf(fp, "%2d %-8s", signum, name);
     132  }
     133  
     134  static void print_all_signals(FILE *fp, int pretty)
     135  {
     136  	size_t n, lth, lpos = 0, width;
     137  	const char *signame = NULL;
     138  	int signum = 0;
     139  
     140  	if (!pretty) {
     141  		for (n = 0; get_signame_by_idx(n, &signame, NULL) == 0; n++) {
     142  			lth = 1 + strlen(signame);
     143  			if (KILL_OUTPUT_WIDTH < lpos + lth) {
     144  				fputc('\n', fp);
     145  				lpos = 0;
     146  			} else if (lpos)
     147  				fputc(' ', fp);
     148  			lpos += lth;
     149  			fputs(signame, fp);
     150  		}
     151  #ifdef SIGRTMIN
     152  		fputs(" RT<N> RTMIN+<N> RTMAX-<N>", fp);
     153  #endif
     154  		fputc('\n', fp);
     155  		return;
     156  	}
     157  
     158  	/* pretty print */
     159  	width = get_terminal_width(KILL_OUTPUT_WIDTH + 1) - 1;
     160  	for (n = 0; get_signame_by_idx(n, &signame, &signum) == 0; n++)
     161  		pretty_print_signal(fp, width, &lpos, signum, signame);
     162  #ifdef SIGRTMIN
     163  	pretty_print_signal(fp, width, &lpos, SIGRTMIN, "RTMIN");
     164  	pretty_print_signal(fp, width, &lpos, SIGRTMAX, "RTMAX");
     165  #endif
     166  	fputc('\n', fp);
     167  }
     168  
     169  static void err_nosig(char *name)
     170  {
     171  	warnx(_("unknown signal %s; valid signals:"), name);
     172  	print_all_signals(stderr, 1);
     173  	exit(EXIT_FAILURE);
     174  }
     175  
     176  static int arg_to_signum(char *arg, int maskbit)
     177  {
     178  	int numsig;
     179  	char *ep;
     180  
     181  	if (isdigit(*arg)) {
     182  		errno = 0;
     183  		numsig = strtol(arg, &ep, 10);
     184  		if (NSIG <= numsig && maskbit && (numsig & 128) != 0)
     185  			numsig -= 128;
     186  		if (errno || *ep != 0 || numsig < 0 || NSIG <= numsig)
     187  			return -1;
     188  		return numsig;
     189  	}
     190  	return signame_to_signum(arg);
     191  }
     192  
     193  static void __attribute__((__noreturn__)) usage(void)
     194  {
     195  	FILE *out = stdout;
     196  	fputs(USAGE_HEADER, out);
     197  	fprintf(out, _(" %s [options] <pid>|<name>...\n"), program_invocation_short_name);
     198  
     199  	fputs(USAGE_SEPARATOR, out);
     200  	fputs(_("Forcibly terminate a process.\n"), out);
     201  
     202  	fputs(USAGE_OPTIONS, out);
     203  	fputs(_(" -a, --all              do not restrict the name-to-pid conversion to processes\n"
     204  		"                          with the same uid as the present process\n"), out);
     205  	fputs(_(" -s, --signal <signal>  send this <signal> instead of SIGTERM\n"), out);
     206  #ifdef HAVE_SIGQUEUE
     207  	fputs(_(" -q, --queue <value>    use sigqueue(2), not kill(2), and pass <value> as data\n"), out);
     208  #endif
     209  #ifdef UL_HAVE_PIDFD
     210  	fputs(_("     --timeout <milliseconds> <follow-up signal>\n"
     211  		"                        wait up to timeout and send follow-up signal\n"), out);
     212  #endif
     213  	fputs(_(" -p, --pid              print pids without signaling them\n"), out);
     214  	fputs(_(" -l, --list[=<signal>]  list signal names, or convert a signal number to a name\n"), out);
     215  	fputs(_(" -L, --table            list signal names and numbers\n"), out);
     216  	fputs(_(" -r, --require-handler  do not send signal if signal handler is not present\n"), out);
     217  	fputs(_("     --verbose          print pids that will be signaled\n"), out);
     218  
     219  	fputs(USAGE_SEPARATOR, out);
     220  	printf(USAGE_HELP_OPTIONS(24));
     221  	printf(USAGE_MAN_TAIL("kill(1)"));
     222  
     223  	exit(EXIT_SUCCESS);
     224  }
     225  
     226  static void __attribute__((__noreturn__)) print_kill_version(void)
     227  {
     228  	static const char *features[] = {
     229  #ifdef HAVE_SIGQUEUE
     230  		"sigqueue",
     231  #endif
     232  #ifdef UL_HAVE_PIDFD
     233  		"pidfd",
     234  #endif
     235  	};
     236  
     237  	printf(_("%s from %s"), program_invocation_short_name, PACKAGE_STRING);
     238  
     239  	if (ARRAY_SIZE(features)) {
     240  		size_t i;
     241  		fputs(_(" (with: "), stdout);
     242  		for (i = 0; i < ARRAY_SIZE(features); i++) {
     243  			fputs(features[i], stdout);
     244  			if (i + 1 < ARRAY_SIZE(features))
     245  				fputs(", ", stdout);
     246  		}
     247  		fputs(")\n", stdout);
     248  	}
     249  	exit(EXIT_SUCCESS);
     250  }
     251  
     252  static char **parse_arguments(int argc, char **argv, struct kill_control *ctl)
     253  {
     254  	char *arg;
     255  
     256  	/* Loop through the arguments.  Actually, -a is the only option
     257  	 * can be used with other options.  The 'kill' is basically a
     258  	 * one-option-at-most program. */
     259  	for (argc--, argv++; 0 < argc; argc--, argv++) {
     260  		arg = *argv;
     261  		if (*arg != '-')
     262  			break;
     263  		if (!strcmp(arg, "--")) {
     264  			argc--, argv++;
     265  			break;
     266  		}
     267  		if (!strcmp(arg, "-v") || !strcmp(arg, "-V") ||
     268  		    !strcmp(arg, "--version"))
     269  			print_kill_version();
     270  		if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
     271  			usage();
     272  		if (!strcmp(arg, "--verbose")) {
     273  			ctl->verbose = 1;
     274  			continue;
     275  		}
     276  		if (!strcmp(arg, "-a") || !strcmp(arg, "--all")) {
     277  			ctl->check_all = 1;
     278  			continue;
     279  		}
     280  		if (!strcmp(arg, "-l") || !strcmp(arg, "--list")) {
     281  			if (argc < 2) {
     282  				print_all_signals(stdout, 0);
     283  				exit(EXIT_SUCCESS);
     284  			}
     285  			if (2 < argc)
     286  				errx(EXIT_FAILURE, _("too many arguments"));
     287  			/* argc == 2, accept "kill -l $?" */
     288  			arg = argv[1];
     289  			if ((ctl->numsig = arg_to_signum(arg, 1)) < 0)
     290  				errx(EXIT_FAILURE, _("unknown signal: %s"),
     291  				     arg);
     292  			print_signal_name(ctl->numsig);
     293  			exit(EXIT_SUCCESS);
     294  		}
     295  		/* for compatibility with procps kill(1) */
     296  		if (!strncmp(arg, "--list=", 7) || !strncmp(arg, "-l=", 3)) {
     297  			char *p = strchr(arg, '=') + 1;
     298  			if ((ctl->numsig = arg_to_signum(p, 1)) < 0)
     299  				errx(EXIT_FAILURE, _("unknown signal: %s"), p);
     300  			print_signal_name(ctl->numsig);
     301  			exit(EXIT_SUCCESS);
     302  		}
     303  		if (!strcmp(arg, "-L") || !strcmp(arg, "--table")) {
     304  			print_all_signals(stdout, 1);
     305  			exit(EXIT_SUCCESS);
     306  		}
     307  		if (!strcmp(arg, "-r") || !strcmp(arg, "--require-handler")) {
     308  			ctl->require_handler = 1;
     309  			continue;
     310  		}
     311  		if (!strcmp(arg, "-p") || !strcmp(arg, "--pid")) {
     312  			ctl->do_pid = 1;
     313  			if (ctl->do_kill)
     314  				errx(EXIT_FAILURE, _("%s and %s are mutually exclusive"), "--pid", "--signal");
     315  #ifdef HAVE_SIGQUEUE
     316  			if (ctl->use_sigval)
     317  				errx(EXIT_FAILURE, _("%s and %s are mutually exclusive"), "--pid", "--queue");
     318  #endif
     319  			continue;
     320  		}
     321  		if (!strcmp(arg, "-s") || !strcmp(arg, "--signal")) {
     322  			if (argc < 2)
     323  				errx(EXIT_FAILURE, _("not enough arguments"));
     324  			ctl->do_kill = 1;
     325  			if (ctl->do_pid)
     326  				errx(EXIT_FAILURE, _("%s and %s are mutually exclusive"), "--pid", "--signal");
     327  			argc--, argv++;
     328  			arg = *argv;
     329  			if ((ctl->numsig = arg_to_signum(arg, 0)) < 0)
     330  				err_nosig(arg);
     331  			continue;
     332  		}
     333  #ifdef HAVE_SIGQUEUE
     334  		if (!strcmp(arg, "-q") || !strcmp(arg, "--queue")) {
     335  			if (argc < 2)
     336  				errx(EXIT_FAILURE, _("option '%s' requires an argument"), arg);
     337  			if (ctl->do_pid)
     338  				errx(EXIT_FAILURE, _("%s and %s are mutually exclusive"), "--pid", "--queue");
     339  			argc--, argv++;
     340  			arg = *argv;
     341  			ctl->sigdata.sival_int = strtos32_or_err(arg, _("argument error"));
     342  			ctl->use_sigval = 1;
     343  			continue;
     344  		}
     345  #endif
     346  #ifdef UL_HAVE_PIDFD
     347  		if (!strcmp(arg, "--timeout")) {
     348  			struct timeouts *next;
     349  
     350  			ctl->timeout = 1;
     351  			if (argc < 2)
     352  				errx(EXIT_FAILURE, _("option '%s' requires an argument"), arg);
     353  			argc--, argv++;
     354  			arg = *argv;
     355  			next = xcalloc(1, sizeof(*next));
     356  			next->period = strtos32_or_err(arg, _("argument error"));
     357  			INIT_LIST_HEAD(&next->follow_ups);
     358  			argc--, argv++;
     359  			arg = *argv;
     360  			if ((next->sig = arg_to_signum(arg, 0)) < 0)
     361  				err_nosig(arg);
     362  			list_add_tail(&next->follow_ups, &ctl->follow_ups);
     363  			continue;
     364  		}
     365  #endif
     366  		/* 'arg' begins with a dash but is not a known option.
     367  		 * So it's probably something like -HUP, or -1/-n try to
     368  		 * deal with it.
     369  		 *
     370  		 * -n could be either signal n or pid -n (a process group
     371  		 * number).  In case of doubt, POSIX tells us to assume a
     372  		 * signal.  But if a signal has already been parsed, then
     373  		 * assume it is a process group, so stop parsing options. */
     374  		if (ctl->do_kill)
     375  			break;
     376  		arg++;
     377  		if ((ctl->numsig = arg_to_signum(arg, 0)) < 0)
     378  			errx(EXIT_FAILURE, _("invalid signal name or number: %s"), arg);
     379  		ctl->do_kill = 1;
     380  		if (ctl->do_pid)
     381  			errx(EXIT_FAILURE, _("%s and %s are mutually exclusive"), "--pid", "--signal");
     382  	}
     383  	if (!*argv)
     384  		errx(EXIT_FAILURE, _("not enough arguments"));
     385  	return argv;
     386  }
     387  
     388  #ifdef UL_HAVE_PIDFD
     389  static int kill_with_timeout(const struct kill_control *ctl)
     390  {
     391  	int pfd, n;
     392  	struct pollfd p = { 0 };
     393  	siginfo_t info = { 0 };
     394  	struct list_head *entry;
     395  
     396  	info.si_code = SI_QUEUE;
     397  	info.si_signo = ctl->numsig;
     398  	info.si_uid = getuid();
     399  	info.si_pid = getpid();
     400  	info.si_value.sival_int =
     401  	    ctl->use_sigval != 0 ? ctl->use_sigval : ctl->numsig;
     402  
     403  	if ((pfd = pidfd_open(ctl->pid, 0)) < 0)
     404  		err(EXIT_FAILURE, _("pidfd_open() failed: %d"), ctl->pid);
     405  	p.fd = pfd;
     406  	p.events = POLLIN;
     407  
     408  	if (pidfd_send_signal(pfd, ctl->numsig, &info, 0) < 0)
     409  		err(EXIT_FAILURE, _("pidfd_send_signal() failed"));
     410  	list_for_each(entry, &ctl->follow_ups) {
     411  		struct timeouts *timeout;
     412  
     413  		timeout = list_entry(entry, struct timeouts, follow_ups);
     414  		n = poll(&p, 1, timeout->period);
     415  		if (n < 0)
     416  			err(EXIT_FAILURE, _("poll() failed"));
     417  		if (n == 0) {
     418  			info.si_signo = timeout->sig;
     419  			if (ctl->verbose)
     420  				printf(_("timeout, sending signal %d to pid %d\n"),
     421  					 timeout->sig, ctl->pid);
     422  			if (pidfd_send_signal(pfd, timeout->sig, &info, 0) < 0)
     423  				err(EXIT_FAILURE, _("pidfd_send_signal() failed"));
     424  		}
     425  	}
     426  	return 0;
     427  }
     428  #endif
     429  
     430  static int kill_verbose(const struct kill_control *ctl)
     431  {
     432  	int rc = 0;
     433  
     434  	if (ctl->verbose)
     435  		printf(_("sending signal %d to pid %d\n"), ctl->numsig, ctl->pid);
     436  	if (ctl->do_pid) {
     437  		printf("%ld\n", (long) ctl->pid);
     438  		return 0;
     439  	}
     440  #ifdef UL_HAVE_PIDFD
     441  	if (ctl->timeout) {
     442  		rc = kill_with_timeout(ctl);
     443  	} else
     444  #endif
     445  #ifdef HAVE_SIGQUEUE
     446  	if (ctl->use_sigval)
     447  		rc = sigqueue(ctl->pid, ctl->numsig, ctl->sigdata);
     448  	else
     449  #endif
     450  		rc = kill(ctl->pid, ctl->numsig);
     451  
     452  	if (rc < 0)
     453  		warn(_("sending signal to %s failed"), ctl->arg);
     454  	return rc;
     455  }
     456  
     457  static int check_signal_handler(const struct kill_control *ctl)
     458  {
     459  	uintmax_t sigcgt = 0;
     460  	int rc = 0, has_hnd = 0;
     461  	struct path_cxt *pc;
     462  
     463  	if (!ctl->require_handler)
     464  		return 1;
     465  
     466  	pc = ul_new_procfs_path(ctl->pid, NULL);
     467  	if (!pc)
     468  		return -ENOMEM;
     469  
     470  	rc = procfs_process_get_stat_nth(pc, 34, &sigcgt);
     471  	if (rc)
     472  		return -EINVAL;
     473  
     474  	ul_unref_path(pc);
     475  
     476  	has_hnd = ((1UL << (ctl->numsig - 1)) & sigcgt) != 0;
     477  	if (ctl->verbose && !has_hnd)
     478  		printf(_("not signalling pid %d, it has no userspace handler for signal %d\n"), ctl->pid, ctl->numsig);
     479  
     480  	return has_hnd;
     481  }
     482  
     483  int main(int argc, char **argv)
     484  {
     485  	struct kill_control ctl = { .numsig = SIGTERM };
     486  	int nerrs = 0, ct = 0;
     487  
     488  	setlocale(LC_ALL, "");
     489  	bindtextdomain(PACKAGE, LOCALEDIR);
     490  	textdomain(PACKAGE);
     491  	close_stdout_atexit();
     492  
     493  #ifdef UL_HAVE_PIDFD
     494  	INIT_LIST_HEAD(&ctl.follow_ups);
     495  #endif
     496  	argv = parse_arguments(argc, argv, &ctl);
     497  
     498  	/* The rest of the arguments should be process ids and names. */
     499  	for ( ; (ctl.arg = *argv) != NULL; argv++) {
     500  		char *ep = NULL;
     501  
     502  		errno = 0;
     503  		ctl.pid = strtol(ctl.arg, &ep, 10);
     504  		if (errno == 0 && ep && *ep == '\0' && ctl.arg < ep) {
     505  			if (check_signal_handler(&ctl) <= 0)
     506  				continue;
     507  			if (kill_verbose(&ctl) != 0)
     508  				nerrs++;
     509  			ct++;
     510  		} else {
     511  			int found = 0;
     512  			struct dirent *d;
     513  			DIR *dir = opendir(_PATH_PROC);
     514  			uid_t uid = !ctl.check_all ? getuid() : 0;
     515  
     516  			if (!dir)
     517  				continue;
     518  
     519  			while ((d = xreaddir(dir))) {
     520  				if (!ctl.check_all &&
     521  				    !procfs_dirent_match_uid(dir, d, uid))
     522  					continue;
     523  				if (ctl.arg &&
     524  				    !procfs_dirent_match_name(dir, d, ctl.arg))
     525  					continue;
     526  				if (procfs_dirent_get_pid(d, &ctl.pid) != 0)
     527  					continue;
     528  				if (check_signal_handler(&ctl) <= 0)
     529  					continue;
     530  
     531  				if (kill_verbose(&ctl) != 0)
     532  					nerrs++;
     533  				ct++;
     534  				found = 1;
     535  			}
     536  
     537  			closedir(dir);
     538  			if (!found) {
     539  				nerrs++, ct++;
     540  				warnx(_("cannot find process \"%s\""), ctl.arg);
     541  			}
     542  		}
     543  	}
     544  
     545  #ifdef UL_HAVE_PIDFD
     546  	while (!list_empty(&ctl.follow_ups)) {
     547  		struct timeouts *x = list_entry(ctl.follow_ups.next,
     548  				                  struct timeouts, follow_ups);
     549  		list_del(&x->follow_ups);
     550  		free(x);
     551  	}
     552  #endif
     553  	if (ct && nerrs == 0)
     554  		return EXIT_SUCCESS;	/* full success */
     555  	if (ct == nerrs)
     556  		return EXIT_FAILURE;	/* all failed */
     557  
     558  	return KILL_EXIT_SOMEOK;	/* partial success */
     559  }
     560