diff options
-rw-r--r-- | bin/kill/kill.c | 17 | ||||
-rw-r--r-- | bin/sh/bltin/bltin.h | 2 | ||||
-rw-r--r-- | bin/sh/jobs.c | 19 | ||||
-rw-r--r-- | bin/sh/tests/builtins/Makefile | 2 | ||||
-rw-r--r-- | bin/sh/tests/builtins/kill2.0 | 7 |
5 files changed, 30 insertions, 17 deletions
diff --git a/bin/kill/kill.c b/bin/kill/kill.c index ab1701e..b23c00a 100644 --- a/bin/kill/kill.c +++ b/bin/kill/kill.c @@ -67,7 +67,7 @@ static void usage(void); int main(int argc, char *argv[]) { - int errors, numsig, pid; + int errors, numsig, pid, ret; char *ep; if (argc < 2) @@ -133,22 +133,17 @@ main(int argc, char *argv[]) for (errors = 0; argc; argc--, argv++) { #ifdef SHELL - if (**argv == '%') { - pid = getjobpgrp(*argv); - /* - * Silently ignore terminated jobs, like the kernel - * silently ignores zombies. - */ - if (pid == 0) - continue; - } else + if (**argv == '%') + ret = killjob(*argv, numsig); + else #endif { pid = strtol(*argv, &ep, 10); if (!**argv || *ep) errx(2, "illegal process id: %s", *argv); + ret = kill(pid, numsig); } - if (kill(pid, numsig) == -1) { + if (ret == -1) { warn("%s", *argv); errors = 1; } diff --git a/bin/sh/bltin/bltin.h b/bin/sh/bltin/bltin.h index 0143b6e..bbf55f1 100644 --- a/bin/sh/bltin/bltin.h +++ b/bin/sh/bltin/bltin.h @@ -74,6 +74,6 @@ pointer stalloc(int); void error(const char *, ...) __printf0like(1, 2); -pid_t getjobpgrp(char *); +int killjob(const char *, int); extern char *commandname; diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index 9913a28..ae89671 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -95,9 +95,9 @@ static void restartjob(struct job *); #endif static void freejob(struct job *); static int waitcmdloop(struct job *); -pid_t getjobpgrp(char *); static struct job *getjob_nonotfound(const char *); static struct job *getjob(const char *); +pid_t killjob(const char *, int); static pid_t dowait(int, struct job *); static void checkzombies(void); static void cmdtxt(union node *); @@ -639,15 +639,26 @@ getjob(const char *name) } -pid_t -getjobpgrp(char *name) +int +killjob(const char *name, int sig) { struct job *jp; + int i, ret; jp = getjob(name); if (jp->state == JOBDONE) return 0; - return -jp->ps[0].pid; + if (jp->jobctl) + return kill(-jp->ps[0].pid, sig); + ret = -1; + errno = ESRCH; + for (i = 0; i < jp->nprocs; i++) + if (jp->ps[i].status == -1 || WIFSTOPPED(jp->ps[i].status)) { + if (kill(jp->ps[i].pid, sig) == 0) + ret = 0; + } else + ret = 0; + return ret; } /* diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile index b76d631..945a14d 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -86,7 +86,7 @@ FILES+= hash3.0 hash3.0.stdout FILES+= hash4.0 FILES+= jobid1.0 FILES+= jobid2.0 -FILES+= kill1.0 +FILES+= kill1.0 kill2.0 FILES+= lineno.0 lineno.0.stdout FILES+= lineno2.0 FILES+= local1.0 diff --git a/bin/sh/tests/builtins/kill2.0 b/bin/sh/tests/builtins/kill2.0 new file mode 100644 index 0000000..31e0ba3 --- /dev/null +++ b/bin/sh/tests/builtins/kill2.0 @@ -0,0 +1,7 @@ +# $FreeBSD$ + +sleep 1 | sleep 1 & +kill %+ +wait "$!" +r=$? +[ "$r" -gt 128 ] && [ "$(kill -l "$r")" = TERM ] |