home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1988, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- /*
- * oct 5 1994 -- almost entirely re-written to allow for process names.
- * modifications (c) salvatore valente <svalente@mit.edu>
- * may be used / modified / distributed under the same terms as the original.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <unistd.h>
- #include <signal.h>
-
- #ifdef __linux__
- /*
- * sys_signame -- an ordered list of signals.
- * lifted from /usr/include/linux/signal.h
- * this particular order is only correct for linux.
- * this is _not_ portable.
- */
- char *sys_signame[NSIG] = {
- "zero", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", "UNUSED",
- "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM",
- "STKFLT","CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "IO",
- "XCPU", "XFSZ", "VTALRM","PROF", "WINCH", NULL
- };
- #endif
-
- int main (int argc, char *argv[]);
- char *mybasename(char *pathname);
- int signame_to_signum (char *sig);
- int arg_to_signum (char *arg);
- void nosig (char *name);
- void printsig (int sig);
- void printsignals (FILE *fp);
- int usage (int status);
- int kill_verbose (char *procname, int pid, int sig);
-
- extern int *get_pids (char *, int);
-
- char version_string[] = "kill v2.0\n";
- char *whoami;
-
- int main (int argc, char *argv[])
- {
- int errors, numsig, pid;
- char *ep, *arg;
- int do_pid, do_kill, check_all;
- int *pids, *ip;
-
- whoami = mybasename (*argv);
- numsig = SIGTERM;
- do_pid = (! strcmp (whoami, "pid"));
- do_kill = 0;
- check_all = 0;
-
- /* loop through the arguments.
- actually, -a is the only option can be used with other options.
- `kill' is basically a one-option-at-most program. */
- for (argc--, argv++; argc > 0; argc--, argv++) {
- arg = *argv;
- if (*arg != '-') {
- break;
- }
- if (! strcmp (arg, "-u")) {
- return usage (0);
- }
- if (! strcmp (arg, "-v")) {
- fputs (version_string, stdout);
- return 0;
- }
- if (! strcmp (arg, "-a")) {
- check_all++;
- continue;
- }
- if (! strcmp (arg, "-l")) {
- if (argc < 2) {
- printsignals (stdout);
- return 0;
- }
- if (argc > 2) {
- return usage (1);
- }
- /* argc == 2 */
- arg = argv[1];
- if ((numsig = arg_to_signum (arg)) < 0) {
- fprintf (stderr, "%s: unknown signal %s\n", whoami, arg);
- return 1;
- }
- printsig (numsig);
- return 0;
- }
- if (! strcmp (arg, "-p")) {
- do_pid++;
- if (do_kill)
- return usage (1);
- continue;
- }
- if (! strcmp (arg, "-s")) {
- if (argc < 2) {
- return usage (1);
- }
- do_kill++;
- if (do_pid)
- return usage (1);
- argc--, argv++;
- arg = *argv;
- if ((numsig = arg_to_signum (arg)) < 0) {
- nosig (arg);
- return 1;
- }
- continue;
- }
- /* `arg' begins with a dash but is not a known option.
- so it's probably something like -HUP.
- try to deal with it. */
- arg++;
- if ((numsig = arg_to_signum (arg)) < 0) {
- return usage (1);
- }
- do_kill++;
- if (do_pid)
- return usage (1);
- continue;
- }
-
- if (! *argv) {
- return usage (1);
- }
- if (do_pid) {
- numsig = -1;
- }
-
- /* we're done with the options.
- the rest of the arguments should be process ids and names.
- kill them. */
- for (errors = 0; (arg = *argv) != NULL; argv++) {
- pid = strtol (arg, &ep, 10);
- if (! *ep)
- errors += kill_verbose (arg, pid, numsig);
- else {
- pids = get_pids (arg, check_all);
- if (! pids) {
- errors++;
- fprintf (stderr, "%s: can't find process \"%s\"\n",
- whoami, arg);
- continue;
- }
- for (ip = pids; *ip >= 0; ip++)
- errors += kill_verbose (arg, *ip, numsig);
- free (pids);
- }
- }
- return (errors);
- }
-
- char *mybasename (char *path)
- {
- char *cp;
-
- cp = strrchr (path, '/');
- return (cp ? cp + 1 : path);
- }
-
- int signame_to_signum (char *sig)
- {
- int n;
-
- if (! strncasecmp (sig, "sig", 3))
- sig += 3;
- for (n = 1; (n < NSIG) && (sys_signame[n] != NULL); n++) {
- if (! strcasecmp (sys_signame[n], sig))
- return n;
- }
- return (-1);
- }
-
- int arg_to_signum (char *arg)
- {
- int numsig;
- char *ep;
-
- if (isdigit (*arg)) {
- numsig = strtol (arg, &ep, 10);
- if (*ep != 0 || numsig < 0 || numsig >= NSIG)
- return (-1);
- return (numsig);
- }
- return (signame_to_signum (arg));
- }
-
- void nosig (char *name)
- {
- fprintf (stderr, "%s: unknown signal %s; valid signals:\n", whoami, name);
- printsignals (stderr);
- }
-
- void printsig (int sig)
- {
- printf ("%s\n", sys_signame[sig]);
- }
-
- void printsignals (FILE *fp)
- {
- int n;
-
- for (n = 1; (n < NSIG) && (sys_signame[n] != NULL); n++) {
- fputs (sys_signame[n], fp);
- if (n == (NSIG / 2) || n == (NSIG - 1))
- fputc ('\n', fp);
- else
- fputc (' ', fp);
- }
- if (n < (NSIG - 1))
- fputc ('\n', fp);
- }
-
- int usage (int status)
- {
- FILE *fp;
-
- fp = (status == 0 ? stdout : stderr);
- fprintf (fp, "usage: %s [ -s signal | -p ] [ -a ] pid ...\n", whoami);
- fprintf (fp, " %s -l [ signal ]\n", whoami);
- return status;
- }
-
- int kill_verbose (char *procname, int pid, int sig)
- {
- if (sig < 0) {
- printf ("%d\n", pid);
- return 0;
- }
- if (kill (pid, sig) < 0) {
- fprintf (stderr, "%s ", whoami);
- perror (procname);
- return 1;
- }
- return 0;
- }
-