summaryrefslogtreecommitdiff
path: root/src/kill.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kill.c')
-rw-r--r--src/kill.c285
1 files changed, 113 insertions, 172 deletions
diff --git a/src/kill.c b/src/kill.c
index c59025f..cb7798c 100644
--- a/src/kill.c
+++ b/src/kill.c
@@ -1,10 +1,10 @@
/* kill -- send a signal to a process
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -12,8 +12,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Paul Eggert. */
@@ -23,25 +22,17 @@
#include <sys/types.h>
#include <signal.h>
-#if HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-#ifndef WIFSIGNALED
-# define WIFSIGNALED(s) (((s) & 0xFFFF) - 1 < (unsigned int) 0xFF)
-#endif
-#ifndef WTERMSIG
-# define WTERMSIG(s) ((s) & 0x7F)
-#endif
-
#include "system.h"
#include "error.h"
#include "sig2str.h"
+#include "operand2sig.h"
+#include "quote.h"
-/* The official name of this program (e.g., no `g' prefix). */
+/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "kill"
-#define AUTHORS "Paul Eggert"
-
+#define AUTHORS proper_name ("Paul Eggert")
+
#if ! (HAVE_DECL_STRSIGNAL || defined strsignal)
# if ! (HAVE_DECL_SYS_SIGLIST || defined sys_siglist)
# if HAVE_DECL__SYS_SIGLIST || defined _sys_siglist
@@ -52,22 +43,19 @@
# endif
# if HAVE_DECL_SYS_SIGLIST || defined sys_siglist
# define strsignal(signum) (0 <= (signum) && (signum) <= SIGNUM_BOUND \
- ? sys_siglist[signum] \
- : 0)
+ ? sys_siglist[signum] \
+ : 0)
# endif
# ifndef strsignal
# define strsignal(signum) 0
# endif
#endif
-
-/* The name this program was run with, for error messages. */
-char *program_name;
static char const short_options[] =
"0::1::2::3::4::5::6::7::8::9::"
- "A::B::C::D::E::F::G::H::I::J::K::L::M::"
+ "A::B::C::D::E::F::G::H::I::J::K::M::"
"N::O::P::Q::R::S::T::U::V::W::X::Y::Z::"
- "ln:s:t";
+ "Lln:s:t";
static struct option const long_options[] =
{
@@ -83,8 +71,7 @@ void
usage (int status)
{
if (status != EXIT_SUCCESS)
- fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
+ emit_try_help ();
else
{
printf (_("\
@@ -92,14 +79,13 @@ Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\
or: %s -l [SIGNAL]...\n\
or: %s -t [SIGNAL]...\n\
"),
- program_name, program_name, program_name);
+ program_name, program_name, program_name);
fputs (_("\
Send signals to processes, or list signals.\n\
-\n\
-"), stdout);
- fputs (_("\
-Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
+
+ emit_mandatory_arg_note ();
+
fputs (_("\
-s, --signal=SIGNAL, -SIGNAL\n\
specify the name or number of the signal to be sent\n\
@@ -109,73 +95,27 @@ Mandatory arguments to long options are mandatory for short options too.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\n\
-SIGNAL may be a signal name like `HUP', or a signal number like `1',\n\
-or an exit status of a process terminated by a signal.\n\
+SIGNAL may be a signal name like 'HUP', or a signal number like '1',\n\
+or the exit status of a process terminated by a signal.\n\
PID is an integer; if negative it identifies a process group.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
-
-/* Convert OPERAND to a signal number with printable representation SIGNAME.
- Return the signal number, or -1 if unsuccessful. */
-static int
-operand2sig (char const *operand, char *signame)
-{
- int signum;
-
- if (ISDIGIT (*operand))
- {
- char *endp;
- long int l = (errno = 0, strtol (operand, &endp, 10));
- int i = l;
- signum = (operand == endp || *endp || errno || i != l ? -1
- : WIFSIGNALED (i) ? WTERMSIG (i)
- : i);
- }
- else
- {
- /* Convert signal to upper case in the C locale, not in the
- current locale. Don't assume ASCII; it might be EBCDIC. */
- char *upcased = xstrdup (operand);
- char *p;
- for (p = upcased; *p; p++)
- if (strchr ("abcdefghijklmnopqrstuvwxyz", *p))
- *p += 'A' - 'a';
-
- /* Look for the signal name, possibly prefixed by "SIG",
- and possibly lowercased. */
- if (! (str2sig (upcased, &signum) == 0
- || (upcased[0] == 'S' && upcased[1] == 'I' && upcased[2] == 'G'
- && str2sig (upcased + 3, &signum) == 0)))
- signum = -1;
-
- free (upcased);
- }
-
- if (signum < 0 || sig2str (signum, signame) != 0)
- {
- error (0, 0, _("%s: invalid signal"), operand);
- return -1;
- }
-
- return signum;
-}
-
-/* Print a row of `kill -t' output. NUM_WIDTH is the maximum signal
+/* Print a row of 'kill -t' output. NUM_WIDTH is the maximum signal
number width, and SIGNUM is the signal number to print. The
maximum name width is NAME_WIDTH, and SIGNAME is the name to print. */
static void
-print_table_row (unsigned int num_width, int signum,
- unsigned int name_width, char const *signame)
+print_table_row (int num_width, int signum,
+ int name_width, char const *signame)
{
char const *description = strsignal (signum);
printf ("%*d %-*s %s\n", num_width, signum, name_width, signame,
- description ? description : "?");
+ description ? description : "?");
}
/* Print a list of signal names. If TABLE, print a table.
@@ -196,56 +136,56 @@ list_signals (bool table, char *const *argv)
/* Compute the maximum width of a signal number. */
unsigned int num_width = 1;
for (signum = 1; signum <= SIGNUM_BOUND / 10; signum *= 10)
- num_width++;
+ num_width++;
/* Compute the maximum width of a signal name. */
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
- if (sig2str (signum, signame) == 0)
- {
- size_t len = strlen (signame);
- if (name_width < len)
- name_width = len;
- }
+ if (sig2str (signum, signame) == 0)
+ {
+ size_t len = strlen (signame);
+ if (name_width < len)
+ name_width = len;
+ }
if (argv)
- for (; *argv; argv++)
- {
- signum = operand2sig (*argv, signame);
- if (signum < 0)
- status = EXIT_FAILURE;
- else
- print_table_row (num_width, signum, name_width, signame);
- }
+ for (; *argv; argv++)
+ {
+ signum = operand2sig (*argv, signame);
+ if (signum < 0)
+ status = EXIT_FAILURE;
+ else
+ print_table_row (num_width, signum, name_width, signame);
+ }
else
- for (signum = 1; signum <= SIGNUM_BOUND; signum++)
- if (sig2str (signum, signame) == 0)
- print_table_row (num_width, signum, name_width, signame);
+ for (signum = 1; signum <= SIGNUM_BOUND; signum++)
+ if (sig2str (signum, signame) == 0)
+ print_table_row (num_width, signum, name_width, signame);
}
else
{
if (argv)
- for (; *argv; argv++)
- {
- signum = operand2sig (*argv, signame);
- if (signum < 0)
- status = EXIT_FAILURE;
- else
- {
- if (ISDIGIT (**argv))
- puts (signame);
- else
- printf ("%d\n", signum);
- }
- }
+ for (; *argv; argv++)
+ {
+ signum = operand2sig (*argv, signame);
+ if (signum < 0)
+ status = EXIT_FAILURE;
+ else
+ {
+ if (ISDIGIT (**argv))
+ puts (signame);
+ else
+ printf ("%d\n", signum);
+ }
+ }
else
- for (signum = 1; signum <= SIGNUM_BOUND; signum++)
- if (sig2str (signum, signame) == 0)
- puts (signame);
+ for (signum = 1; signum <= SIGNUM_BOUND; signum++)
+ if (sig2str (signum, signame) == 0)
+ puts (signame);
}
return status;
}
-
+
/* Send signal SIGNUM to all the processes or process groups specified
by ARGV. Return a suitable exit status. */
@@ -262,21 +202,21 @@ send_signals (int signum, char *const *argv)
pid_t pid = n;
if (errno == ERANGE || pid != n || arg == endp || *endp)
- {
- error (0, 0, _("%s: invalid process id"), arg);
- status = EXIT_FAILURE;
- }
+ {
+ error (0, 0, _("%s: invalid process id"), quote (arg));
+ status = EXIT_FAILURE;
+ }
else if (kill (pid, signum) != 0)
- {
- error (0, errno, "%s", arg);
- status = EXIT_FAILURE;
- }
+ {
+ error (0, errno, "%s", quote (arg));
+ status = EXIT_FAILURE;
+ }
}
while ((arg = *++argv));
return status;
}
-
+
int
main (int argc, char **argv)
{
@@ -287,7 +227,7 @@ main (int argc, char **argv)
char signame[SIG2STR_MAX];
initialize_main (&argc, &argv);
- program_name = argv[0];
+ set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
@@ -295,63 +235,64 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))
- != -1)
+ != -1)
switch (optc)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- if (optind != 2)
- {
- /* This option is actually a process-id. */
- optind--;
- goto no_more_options;
- }
- /* Fall through. */
+ if (optind != 2)
+ {
+ /* This option is actually a process-id. */
+ optind--;
+ goto no_more_options;
+ }
+ /* Fall through. */
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
- case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'K': /*case 'L':*/ case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
- if (! optarg)
- optarg = argv[optind - 1] + strlen (argv[optind - 1]);
- if (optarg != argv[optind - 1] + 2)
- {
- error (0, 0, _("invalid option -- %c"), optc);
- usage (EXIT_FAILURE);
- }
- optarg--;
- /* Fall through. */
+ if (! optarg)
+ optarg = argv[optind - 1] + strlen (argv[optind - 1]);
+ if (optarg != argv[optind - 1] + 2)
+ {
+ error (0, 0, _("invalid option -- %c"), optc);
+ usage (EXIT_FAILURE);
+ }
+ optarg--;
+ /* Fall through. */
case 'n': /* -n is not documented, but is for Bash compatibility. */
case 's':
- if (0 <= signum)
- {
- error (0, 0, _("%s: multiple signals specified"), optarg);
- usage (EXIT_FAILURE);
- }
- signum = operand2sig (optarg, signame);
- if (signum < 0)
- usage (EXIT_FAILURE);
- break;
-
+ if (0 <= signum)
+ {
+ error (0, 0, _("%s: multiple signals specified"), quote (optarg));
+ usage (EXIT_FAILURE);
+ }
+ signum = operand2sig (optarg, signame);
+ if (signum < 0)
+ usage (EXIT_FAILURE);
+ break;
+
+ case 'L': /* -L is not documented, but is for procps compatibility. */
case 't':
- table = true;
- /* Fall through. */
+ table = true;
+ /* Fall through. */
case 'l':
- if (list)
- {
- error (0, 0, _("multiple -l or -t options specified"));
- usage (EXIT_FAILURE);
- }
- list = true;
- break;
+ if (list)
+ {
+ error (0, 0, _("multiple -l or -t options specified"));
+ usage (EXIT_FAILURE);
+ }
+ list = true;
+ break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE);
}
- no_more_options:;
+ no_more_options:
if (signum < 0)
signum = SIGTERM;
@@ -368,6 +309,6 @@ main (int argc, char **argv)
}
return (list
- ? list_signals (table, optind < argc ? argv + optind : NULL)
- : send_signals (signum, argv + optind));
+ ? list_signals (table, optind < argc ? argv + optind : NULL)
+ : send_signals (signum, argv + optind));
}