From 0a62a9caa9b95a5ae7fe502628ef0fd31dca16bd Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Tue, 21 Dec 2010 22:47:34 +0000 Subject: [PATCH] sh: Add kill builtin. This allows specifying a %job (which is equivalent to the corresponding process group). Additionally, it improves reliability of kill from sh in high-load situations and ensures "kill" finds the correct utility regardless of PATH, as required by POSIX (unless the undocumented %builtin mechanism is used). Side effect: fatal errors (any error other than kill(2) failure) now return exit status 2 instead of 1. (This is consistent with other sh builtins, but not in NetBSD.) Code size increases about 1K on i386. Obtained from: NetBSD --- bin/kill/kill.1 | 1 + bin/kill/kill.c | 43 ++++++++++++++++++++++++++++++---------- bin/sh/Makefile | 3 ++- bin/sh/bltin/bltin.h | 5 +++++ bin/sh/builtins.def | 1 + bin/sh/jobs.c | 8 ++++++++ bin/sh/sh.1 | 7 ++++++- share/man/man1/builtin.1 | 4 ++-- 8 files changed, 57 insertions(+), 15 deletions(-) diff --git a/bin/kill/kill.1 b/bin/kill/kill.1 index c666ef59416d..6e77c593e6fb 100644 --- a/bin/kill/kill.1 +++ b/bin/kill/kill.1 @@ -134,6 +134,7 @@ Terminate the process group with PGID 117: .Xr csh 1 , .Xr killall 1 , .Xr ps 1 , +.Xr sh 1 , .Xr kill 2 , .Xr sigaction 2 .Sh STANDARDS diff --git a/bin/kill/kill.c b/bin/kill/kill.c index f4ab2df3e01a..edfc92832648 100644 --- a/bin/kill/kill.c +++ b/bin/kill/kill.c @@ -49,6 +49,12 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef SHELL +#define main killcmd +#include "bltin/bltin.h" +#include "error.h" +#endif + static void nosig(const char *); static void printsignals(FILE *); static int signame_to_signum(const char *); @@ -75,16 +81,16 @@ main(int argc, char *argv[]) usage(); numsig = strtol(*argv, &ep, 10); if (!**argv || *ep) - errx(1, "illegal signal number: %s", *argv); + errx(2, "illegal signal number: %s", *argv); if (numsig >= 128) numsig -= 128; if (numsig <= 0 || numsig >= sys_nsig) nosig(*argv); printf("%s\n", sys_signame[numsig]); - exit(0); + return (0); } printsignals(stdout); - exit(0); + return (0); } if (!strcmp(*argv, "-s")) { @@ -107,7 +113,7 @@ main(int argc, char *argv[]) } else if (isdigit(**argv)) { numsig = strtol(*argv, &ep, 10); if (!**argv || *ep) - errx(1, "illegal signal number: %s", *argv); + errx(2, "illegal signal number: %s", *argv); if (numsig < 0) nosig(*argv); } else @@ -122,16 +128,23 @@ main(int argc, char *argv[]) usage(); for (errors = 0; argc; argc--, argv++) { - pid = strtol(*argv, &ep, 10); - if (!**argv || *ep) - errx(1, "illegal process id: %s", *argv); - else if (kill(pid, numsig) == -1) { +#ifdef SHELL + if (**argv == '%') + pid = getjobpgrp(*argv); + else +#endif + { + pid = strtol(*argv, &ep, 10); + if (!**argv || *ep) + errx(2, "illegal process id: %s", *argv); + } + if (kill(pid, numsig) == -1) { warn("%s", *argv); errors = 1; } } - exit(errors); + return (errors); } static int @@ -154,7 +167,11 @@ nosig(const char *name) warnx("unknown signal %s; valid signals:", name); printsignals(stderr); - exit(1); +#ifdef SHELL + error(NULL); +#else + exit(2); +#endif } static void @@ -180,5 +197,9 @@ usage(void) " kill -l [exit_status]", " kill -signal_name pid ...", " kill -signal_number pid ..."); - exit(1); +#ifdef SHELL + error(NULL); +#else + exit(2); +#endif } diff --git a/bin/sh/Makefile b/bin/sh/Makefile index a606c9be9716..47642dffce7e 100644 --- a/bin/sh/Makefile +++ b/bin/sh/Makefile @@ -4,7 +4,7 @@ PROG= sh INSTALLFLAGS= -S SHSRCS= alias.c arith.y arith_lex.l cd.c echo.c error.c eval.c exec.c expand.c \ - histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \ + histedit.c input.c jobs.c kill.c mail.c main.c memalloc.c miscbltin.c \ mystring.c options.c output.c parser.c printf.c redir.c show.c \ test.c trap.c var.c GENSRCS= builtins.c init.c nodes.c syntax.c @@ -26,6 +26,7 @@ WARNS?= 2 WFORMAT=0 .PATH: ${.CURDIR}/bltin \ + ${.CURDIR}/../kill \ ${.CURDIR}/../test \ ${.CURDIR}/../../usr.bin/printf diff --git a/bin/sh/bltin/bltin.h b/bin/sh/bltin/bltin.h index f6e788365aad..e449673d1d0d 100644 --- a/bin/sh/bltin/bltin.h +++ b/bin/sh/bltin/bltin.h @@ -43,6 +43,7 @@ #include "../mystring.h" #ifdef SHELL #include "../output.h" +#define FILE struct output #undef stdout #define stdout out1 #undef stderr @@ -58,6 +59,7 @@ #define fflush flushout #define INITARGS(argv) #define warnx warning +#define warn(fmt, ...) warning(fmt ": %s", __VA_ARGS__, strerror(errno)) #define errx(exitstatus, ...) error(__VA_ARGS__) #else @@ -67,8 +69,11 @@ #define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else #endif +#include + pointer stalloc(int); void error(const char *, ...) __printf0like(1, 2); +pid_t getjobpgrp(char *); int echocmd(int, char **); int testcmd(int, char **); diff --git a/bin/sh/builtins.def b/bin/sh/builtins.def index b72f8873386b..cfc6361e6cc0 100644 --- a/bin/sh/builtins.def +++ b/bin/sh/builtins.def @@ -70,6 +70,7 @@ hashcmd hash histcmd -h fc jobidcmd jobid jobscmd jobs +killcmd kill localcmd local printfcmd printf pwdcmd pwd diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index 6a781ea13055..fda167b0cfa2 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -632,6 +632,14 @@ currentjob: if ((jp = getcurjob(NULL)) == NULL) } +pid_t +getjobpgrp(char *name) +{ + struct job *jp; + + jp = getjob(name); + return -jp->ps[0].pid; +} /* * Return a new job structure, diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index a6fd7be05248..8f92bbba33b6 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -32,7 +32,7 @@ .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" $FreeBSD$ .\" -.Dd December 3, 2010 +.Dd December 21, 2010 .Dt SH 1 .Os .Sh NAME @@ -2049,6 +2049,10 @@ If the .Fl s option is specified, only the PIDs of the job commands are printed, one per line. +.It Ic kill +A built-in equivalent of +.Xr kill 1 +that additionally supports sending signals to jobs. .It Ic local Oo Ar variable ... Oc Op Fl See the .Sx Functions @@ -2477,6 +2481,7 @@ will return the argument. .Xr echo 1 , .Xr ed 1 , .Xr emacs 1 , +.Xr kill 1 , .Xr printf 1 , .Xr pwd 1 , .Xr test 1 , diff --git a/share/man/man1/builtin.1 b/share/man/man1/builtin.1 index 5a6b5ae739ea..72b016bcd20d 100644 --- a/share/man/man1/builtin.1 +++ b/share/man/man1/builtin.1 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 19, 2010 +.Dd December 21, 2010 .Dt BUILTIN 1 .Os .Sh NAME @@ -251,7 +251,7 @@ but are implemented as scripts using a builtin command of the same name. .It Ic if Ta \&No Ta Yes Ta Yes .It Ic jobid Ta \&No Ta \&No Ta Yes .It Ic jobs Ta No** Ta Yes Ta Yes -.It Ic kill Ta Yes Ta Yes Ta \&No +.It Ic kill Ta Yes Ta Yes Ta Yes .It Ic limit Ta \&No Ta Yes Ta \&No .It Ic local Ta \&No Ta \&No Ta Yes .It Ic log Ta \&No Ta Yes Ta \&No