aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/kill/kill.c17
-rw-r--r--bin/sh/bltin/bltin.h2
-rw-r--r--bin/sh/jobs.c19
-rw-r--r--bin/sh/tests/builtins/Makefile2
-rw-r--r--bin/sh/tests/builtins/kill2.07
5 files changed, 30 insertions, 17 deletions
diff --git a/bin/kill/kill.c b/bin/kill/kill.c
index ab1701e03bdb..b23c00acf21c 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 0143b6e27aca..bbf55f1ae79f 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 9913a289de1a..ae896711037e 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 b76d6312342a..945a14d6c518 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 000000000000..31e0ba362b80
--- /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 ]