| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: pwait.c,v 1.1 2015/03/02 21:43:39 christos Exp $ */ | | 1 | /* $NetBSD: pwait.c,v 1.2 2015/03/02 21:53:48 christos Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2004-2009, Jilles Tjoelker | | 4 | * Copyright (c) 2004-2009, Jilles Tjoelker |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with | | 7 | * Redistribution and use in source and binary forms, with |
8 | * or without modification, are permitted provided that the | | 8 | * or without modification, are permitted provided that the |
9 | * following conditions are met: | | 9 | * following conditions are met: |
10 | * | | 10 | * |
11 | * 1. Redistributions of source code must retain the above | | 11 | * 1. Redistributions of source code must retain the above |
12 | * copyright notice, this list of conditions and the | | 12 | * copyright notice, this list of conditions and the |
13 | * following disclaimer. | | 13 | * following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the | | 14 | * 2. Redistributions in binary form must reproduce the |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | | 27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
28 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | | 28 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | | 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | | 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
32 | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY | | 32 | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
33 | * OF SUCH DAMAGE. | | 33 | * OF SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | #include <sys/cdefs.h> | | 36 | #include <sys/cdefs.h> |
37 | #ifdef __FBSDID | | 37 | #ifdef __FBSDID |
38 | __FBSDID("$FreeBSD: head/bin/pwait/pwait.c 245506 2013-01-16 18:15:25Z delphij $"); | | 38 | __FBSDID("$FreeBSD: head/bin/pwait/pwait.c 245506 2013-01-16 18:15:25Z delphij $"); |
39 | #endif | | 39 | #endif |
40 | __RCSID("$NetBSD: pwait.c,v 1.1 2015/03/02 21:43:39 christos Exp $"); | | 40 | __RCSID("$NetBSD: pwait.c,v 1.2 2015/03/02 21:53:48 christos Exp $"); |
41 | | | 41 | |
42 | #include <sys/types.h> | | 42 | #include <sys/types.h> |
43 | #include <sys/event.h> | | 43 | #include <sys/event.h> |
44 | #include <sys/time.h> | | 44 | #include <sys/time.h> |
45 | #include <sys/wait.h> | | 45 | #include <sys/wait.h> |
46 | | | 46 | |
47 | #include <err.h> | | 47 | #include <err.h> |
48 | #include <errno.h> | | 48 | #include <errno.h> |
49 | #include <fcntl.h> | | 49 | #include <fcntl.h> |
50 | #include <signal.h> | | 50 | #include <signal.h> |
51 | #include <stdio.h> | | 51 | #include <stdio.h> |
52 | #include <stdlib.h> | | 52 | #include <stdlib.h> |
53 | #include <string.h> | | 53 | #include <string.h> |
| @@ -60,91 +60,100 @@ usage(void) | | | @@ -60,91 +60,100 @@ usage(void) |
60 | | | 60 | |
61 | fprintf(stderr, "usage: pwait [-v] pid ...\n"); | | 61 | fprintf(stderr, "usage: pwait [-v] pid ...\n"); |
62 | exit(EX_USAGE); | | 62 | exit(EX_USAGE); |
63 | } | | 63 | } |
64 | | | 64 | |
65 | /* | | 65 | /* |
66 | * pwait - wait for processes to terminate | | 66 | * pwait - wait for processes to terminate |
67 | */ | | 67 | */ |
68 | int | | 68 | int |
69 | main(int argc, char *argv[]) | | 69 | main(int argc, char *argv[]) |
70 | { | | 70 | { |
71 | int kq; | | 71 | int kq; |
72 | struct kevent *e; | | 72 | struct kevent *e; |
73 | int verbose = 0; | | 73 | int verbose = 0, childstatus = 0; |
74 | int opt, nleft, n, i, duplicate, status; | | 74 | int opt, duplicate, status; |
75 | long pid; | | 75 | size_t nleft, n, i; |
| | | 76 | pid_t pid; |
76 | char *s, *end; | | 77 | char *s, *end; |
77 | | | 78 | |
78 | while ((opt = getopt(argc, argv, "v")) != -1) { | | 79 | while ((opt = getopt(argc, argv, "sv")) != -1) { |
79 | switch (opt) { | | 80 | switch (opt) { |
| | | 81 | case 's': |
| | | 82 | childstatus = 1; |
| | | 83 | break; |
80 | case 'v': | | 84 | case 'v': |
81 | verbose = 1; | | 85 | verbose = 1; |
82 | break; | | 86 | break; |
83 | default: | | 87 | default: |
84 | usage(); | | 88 | usage(); |
85 | /* NOTREACHED */ | | 89 | /* NOTREACHED */ |
86 | } | | 90 | } |
87 | } | | 91 | } |
88 | | | 92 | |
89 | argc -= optind; | | 93 | argc -= optind; |
90 | argv += optind; | | 94 | argv += optind; |
91 | | | 95 | |
92 | if (argc == 0) | | 96 | if (argc == 0) |
93 | usage(); | | 97 | usage(); |
94 | | | 98 | |
95 | kq = kqueue(); | | 99 | kq = kqueue(); |
96 | if (kq == -1) | | 100 | if (kq == -1) |
97 | err(1, "kqueue"); | | 101 | err(EXIT_FAILURE, "kqueue"); |
98 | | | 102 | |
99 | e = malloc(argc * sizeof(struct kevent)); | | 103 | e = malloc((size_t)argc * sizeof(*e)); |
100 | if (e == NULL) | | 104 | if (e == NULL) |
101 | err(1, "malloc"); | | 105 | err(EXIT_FAILURE, "malloc"); |
102 | nleft = 0; | | 106 | nleft = 0; |
103 | for (n = 0; n < argc; n++) { | | 107 | for (n = 0; n < (size_t)argc; n++) { |
| | | 108 | long pidl; |
104 | s = argv[n]; | | 109 | s = argv[n]; |
105 | if (!strncmp(s, "/proc/", 6)) /* Undocumented Solaris compat */ | | 110 | if (!strncmp(s, "/proc/", 6)) /* Undocumented Solaris compat */ |
106 | s += 6; | | 111 | s += 6; |
107 | errno = 0; | | 112 | errno = 0; |
108 | pid = strtol(s, &end, 10); | | 113 | pidl = strtol(s, &end, 10); |
109 | if (pid < 0 || *end != '\0' || errno != 0) { | | 114 | if (pidl < 0 || *end != '\0' || errno != 0) { |
110 | warnx("%s: bad process id", s); | | 115 | warnx("%s: bad process id", s); |
111 | continue; | | 116 | continue; |
112 | } | | 117 | } |
| | | 118 | pid = (pid_t)pidl; |
113 | duplicate = 0; | | 119 | duplicate = 0; |
114 | for (i = 0; i < nleft; i++) | | 120 | for (i = 0; i < nleft; i++) |
115 | if (e[i].ident == (uintptr_t)pid) | | 121 | if (e[i].ident == (uintptr_t)pid) |
116 | duplicate = 1; | | 122 | duplicate = 1; |
117 | if (!duplicate) { | | 123 | if (!duplicate) { |
118 | EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, | | 124 | EV_SET(e + nleft, (uintptr_t)pid, EVFILT_PROC, EV_ADD, |
119 | 0, NULL); | | 125 | NOTE_EXIT, 0, NULL); |
120 | if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) | | 126 | if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) |
121 | warn("%ld", pid); | | 127 | warn("%jd", (intmax_t)pid); |
122 | else | | 128 | else |
123 | nleft++; | | 129 | nleft++; |
124 | } | | 130 | } |
125 | } | | 131 | } |
126 | | | 132 | |
127 | while (nleft > 0) { | | 133 | while (nleft > 0) { |
128 | n = kevent(kq, NULL, 0, e, nleft, NULL); | | 134 | int rv = kevent(kq, NULL, 0, e, nleft, NULL); |
129 | if (n == -1) | | 135 | if (rv == -1) |
130 | err(1, "kevent"); | | 136 | err(EXIT_FAILURE, "kevent"); |
131 | if (verbose) | | 137 | for (i = 0; i < n; i++) { |
132 | for (i = 0; i < n; i++) { | | 138 | status = (int)e[i].data; |
133 | status = e[i].data; | | 139 | if (verbose) { |
134 | if (WIFEXITED(status)) | | 140 | if (WIFEXITED(status)) |
135 | printf("%ld: exited with status %d.\n", | | 141 | printf("%ld: exited with status %d.\n", |
136 | (long)e[i].ident, | | 142 | (long)e[i].ident, |
137 | WEXITSTATUS(status)); | | 143 | WEXITSTATUS(status)); |
138 | else if (WIFSIGNALED(status)) | | 144 | else if (WIFSIGNALED(status)) |
139 | printf("%ld: killed by signal %d.\n", | | 145 | printf("%ld: killed by signal %d.\n", |
140 | (long)e[i].ident, | | 146 | (long)e[i].ident, |
141 | WTERMSIG(status)); | | 147 | WTERMSIG(status)); |
142 | else | | 148 | else |
143 | printf("%ld: terminated.\n", | | 149 | printf("%ld: terminated.\n", |
144 | (long)e[i].ident); | | 150 | (long)e[i].ident); |
145 | } | | 151 | } |
| | | 152 | if (childstatus) |
| | | 153 | return status; |
| | | 154 | } |
146 | nleft -= n; | | 155 | nleft -= n; |
147 | } | | 156 | } |
148 | | | 157 | |
149 | exit(EX_OK); | | 158 | return EX_OK; |
150 | } | | 159 | } |