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
This commit is contained in:
parent
05bcfef170
commit
0a62a9caa9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216629
@ -134,6 +134,7 @@ Terminate the process group with PGID 117:
|
|||||||
.Xr csh 1 ,
|
.Xr csh 1 ,
|
||||||
.Xr killall 1 ,
|
.Xr killall 1 ,
|
||||||
.Xr ps 1 ,
|
.Xr ps 1 ,
|
||||||
|
.Xr sh 1 ,
|
||||||
.Xr kill 2 ,
|
.Xr kill 2 ,
|
||||||
.Xr sigaction 2
|
.Xr sigaction 2
|
||||||
.Sh STANDARDS
|
.Sh STANDARDS
|
||||||
|
@ -49,6 +49,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef SHELL
|
||||||
|
#define main killcmd
|
||||||
|
#include "bltin/bltin.h"
|
||||||
|
#include "error.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static void nosig(const char *);
|
static void nosig(const char *);
|
||||||
static void printsignals(FILE *);
|
static void printsignals(FILE *);
|
||||||
static int signame_to_signum(const char *);
|
static int signame_to_signum(const char *);
|
||||||
@ -75,16 +81,16 @@ main(int argc, char *argv[])
|
|||||||
usage();
|
usage();
|
||||||
numsig = strtol(*argv, &ep, 10);
|
numsig = strtol(*argv, &ep, 10);
|
||||||
if (!**argv || *ep)
|
if (!**argv || *ep)
|
||||||
errx(1, "illegal signal number: %s", *argv);
|
errx(2, "illegal signal number: %s", *argv);
|
||||||
if (numsig >= 128)
|
if (numsig >= 128)
|
||||||
numsig -= 128;
|
numsig -= 128;
|
||||||
if (numsig <= 0 || numsig >= sys_nsig)
|
if (numsig <= 0 || numsig >= sys_nsig)
|
||||||
nosig(*argv);
|
nosig(*argv);
|
||||||
printf("%s\n", sys_signame[numsig]);
|
printf("%s\n", sys_signame[numsig]);
|
||||||
exit(0);
|
return (0);
|
||||||
}
|
}
|
||||||
printsignals(stdout);
|
printsignals(stdout);
|
||||||
exit(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(*argv, "-s")) {
|
if (!strcmp(*argv, "-s")) {
|
||||||
@ -107,7 +113,7 @@ main(int argc, char *argv[])
|
|||||||
} else if (isdigit(**argv)) {
|
} else if (isdigit(**argv)) {
|
||||||
numsig = strtol(*argv, &ep, 10);
|
numsig = strtol(*argv, &ep, 10);
|
||||||
if (!**argv || *ep)
|
if (!**argv || *ep)
|
||||||
errx(1, "illegal signal number: %s", *argv);
|
errx(2, "illegal signal number: %s", *argv);
|
||||||
if (numsig < 0)
|
if (numsig < 0)
|
||||||
nosig(*argv);
|
nosig(*argv);
|
||||||
} else
|
} else
|
||||||
@ -122,16 +128,23 @@ main(int argc, char *argv[])
|
|||||||
usage();
|
usage();
|
||||||
|
|
||||||
for (errors = 0; argc; argc--, argv++) {
|
for (errors = 0; argc; argc--, argv++) {
|
||||||
|
#ifdef SHELL
|
||||||
|
if (**argv == '%')
|
||||||
|
pid = getjobpgrp(*argv);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
pid = strtol(*argv, &ep, 10);
|
pid = strtol(*argv, &ep, 10);
|
||||||
if (!**argv || *ep)
|
if (!**argv || *ep)
|
||||||
errx(1, "illegal process id: %s", *argv);
|
errx(2, "illegal process id: %s", *argv);
|
||||||
else if (kill(pid, numsig) == -1) {
|
}
|
||||||
|
if (kill(pid, numsig) == -1) {
|
||||||
warn("%s", *argv);
|
warn("%s", *argv);
|
||||||
errors = 1;
|
errors = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(errors);
|
return (errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -154,7 +167,11 @@ nosig(const char *name)
|
|||||||
|
|
||||||
warnx("unknown signal %s; valid signals:", name);
|
warnx("unknown signal %s; valid signals:", name);
|
||||||
printsignals(stderr);
|
printsignals(stderr);
|
||||||
exit(1);
|
#ifdef SHELL
|
||||||
|
error(NULL);
|
||||||
|
#else
|
||||||
|
exit(2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -180,5 +197,9 @@ usage(void)
|
|||||||
" kill -l [exit_status]",
|
" kill -l [exit_status]",
|
||||||
" kill -signal_name pid ...",
|
" kill -signal_name pid ...",
|
||||||
" kill -signal_number pid ...");
|
" kill -signal_number pid ...");
|
||||||
exit(1);
|
#ifdef SHELL
|
||||||
|
error(NULL);
|
||||||
|
#else
|
||||||
|
exit(2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
PROG= sh
|
PROG= sh
|
||||||
INSTALLFLAGS= -S
|
INSTALLFLAGS= -S
|
||||||
SHSRCS= alias.c arith.y arith_lex.l cd.c echo.c error.c eval.c exec.c expand.c \
|
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 \
|
mystring.c options.c output.c parser.c printf.c redir.c show.c \
|
||||||
test.c trap.c var.c
|
test.c trap.c var.c
|
||||||
GENSRCS= builtins.c init.c nodes.c syntax.c
|
GENSRCS= builtins.c init.c nodes.c syntax.c
|
||||||
@ -26,6 +26,7 @@ WARNS?= 2
|
|||||||
WFORMAT=0
|
WFORMAT=0
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/bltin \
|
.PATH: ${.CURDIR}/bltin \
|
||||||
|
${.CURDIR}/../kill \
|
||||||
${.CURDIR}/../test \
|
${.CURDIR}/../test \
|
||||||
${.CURDIR}/../../usr.bin/printf
|
${.CURDIR}/../../usr.bin/printf
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "../mystring.h"
|
#include "../mystring.h"
|
||||||
#ifdef SHELL
|
#ifdef SHELL
|
||||||
#include "../output.h"
|
#include "../output.h"
|
||||||
|
#define FILE struct output
|
||||||
#undef stdout
|
#undef stdout
|
||||||
#define stdout out1
|
#define stdout out1
|
||||||
#undef stderr
|
#undef stderr
|
||||||
@ -58,6 +59,7 @@
|
|||||||
#define fflush flushout
|
#define fflush flushout
|
||||||
#define INITARGS(argv)
|
#define INITARGS(argv)
|
||||||
#define warnx warning
|
#define warnx warning
|
||||||
|
#define warn(fmt, ...) warning(fmt ": %s", __VA_ARGS__, strerror(errno))
|
||||||
#define errx(exitstatus, ...) error(__VA_ARGS__)
|
#define errx(exitstatus, ...) error(__VA_ARGS__)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -67,8 +69,11 @@
|
|||||||
#define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else
|
#define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
pointer stalloc(int);
|
pointer stalloc(int);
|
||||||
void error(const char *, ...) __printf0like(1, 2);
|
void error(const char *, ...) __printf0like(1, 2);
|
||||||
|
pid_t getjobpgrp(char *);
|
||||||
|
|
||||||
int echocmd(int, char **);
|
int echocmd(int, char **);
|
||||||
int testcmd(int, char **);
|
int testcmd(int, char **);
|
||||||
|
@ -70,6 +70,7 @@ hashcmd hash
|
|||||||
histcmd -h fc
|
histcmd -h fc
|
||||||
jobidcmd jobid
|
jobidcmd jobid
|
||||||
jobscmd jobs
|
jobscmd jobs
|
||||||
|
killcmd kill
|
||||||
localcmd local
|
localcmd local
|
||||||
printfcmd printf
|
printfcmd printf
|
||||||
pwdcmd pwd
|
pwdcmd pwd
|
||||||
|
@ -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,
|
* Return a new job structure,
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
|
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd December 3, 2010
|
.Dd December 21, 2010
|
||||||
.Dt SH 1
|
.Dt SH 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -2049,6 +2049,10 @@ If the
|
|||||||
.Fl s
|
.Fl s
|
||||||
option is specified, only the PIDs of the job commands are printed, one per
|
option is specified, only the PIDs of the job commands are printed, one per
|
||||||
line.
|
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
|
.It Ic local Oo Ar variable ... Oc Op Fl
|
||||||
See the
|
See the
|
||||||
.Sx Functions
|
.Sx Functions
|
||||||
@ -2477,6 +2481,7 @@ will return the argument.
|
|||||||
.Xr echo 1 ,
|
.Xr echo 1 ,
|
||||||
.Xr ed 1 ,
|
.Xr ed 1 ,
|
||||||
.Xr emacs 1 ,
|
.Xr emacs 1 ,
|
||||||
|
.Xr kill 1 ,
|
||||||
.Xr printf 1 ,
|
.Xr printf 1 ,
|
||||||
.Xr pwd 1 ,
|
.Xr pwd 1 ,
|
||||||
.Xr test 1 ,
|
.Xr test 1 ,
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 19, 2010
|
.Dd December 21, 2010
|
||||||
.Dt BUILTIN 1
|
.Dt BUILTIN 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.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 if Ta \&No Ta Yes Ta Yes
|
||||||
.It Ic jobid Ta \&No Ta \&No Ta Yes
|
.It Ic jobid Ta \&No Ta \&No Ta Yes
|
||||||
.It Ic jobs Ta No** Ta Yes 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 limit Ta \&No Ta Yes Ta \&No
|
||||||
.It Ic local Ta \&No Ta \&No Ta Yes
|
.It Ic local Ta \&No Ta \&No Ta Yes
|
||||||
.It Ic log Ta \&No Ta Yes Ta \&No
|
.It Ic log Ta \&No Ta Yes Ta \&No
|
||||||
|
Loading…
Reference in New Issue
Block a user