diff options
-rw-r--r-- | Documentation/accounting/getdelays.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index 6e25c2659e0a..a2976a6de033 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <sys/types.h> | 21 | #include <sys/types.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <sys/socket.h> | 23 | #include <sys/socket.h> |
24 | #include <sys/wait.h> | ||
24 | #include <signal.h> | 25 | #include <signal.h> |
25 | 26 | ||
26 | #include <linux/genetlink.h> | 27 | #include <linux/genetlink.h> |
@@ -266,11 +267,13 @@ int main(int argc, char *argv[]) | |||
266 | int containerset = 0; | 267 | int containerset = 0; |
267 | char containerpath[1024]; | 268 | char containerpath[1024]; |
268 | int cfd = 0; | 269 | int cfd = 0; |
270 | int forking = 0; | ||
271 | sigset_t sigset; | ||
269 | 272 | ||
270 | struct msgtemplate msg; | 273 | struct msgtemplate msg; |
271 | 274 | ||
272 | while (1) { | 275 | while (!forking) { |
273 | c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:"); | 276 | c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:c:"); |
274 | if (c < 0) | 277 | if (c < 0) |
275 | break; | 278 | break; |
276 | 279 | ||
@@ -319,6 +322,28 @@ int main(int argc, char *argv[]) | |||
319 | err(1, "Invalid pid\n"); | 322 | err(1, "Invalid pid\n"); |
320 | cmd_type = TASKSTATS_CMD_ATTR_PID; | 323 | cmd_type = TASKSTATS_CMD_ATTR_PID; |
321 | break; | 324 | break; |
325 | case 'c': | ||
326 | |||
327 | /* Block SIGCHLD for sigwait() later */ | ||
328 | if (sigemptyset(&sigset) == -1) | ||
329 | err(1, "Failed to empty sigset"); | ||
330 | if (sigaddset(&sigset, SIGCHLD)) | ||
331 | err(1, "Failed to set sigchld in sigset"); | ||
332 | sigprocmask(SIG_BLOCK, &sigset, NULL); | ||
333 | |||
334 | /* fork/exec a child */ | ||
335 | tid = fork(); | ||
336 | if (tid < 0) | ||
337 | err(1, "Fork failed\n"); | ||
338 | if (tid == 0) | ||
339 | if (execvp(argv[optind - 1], | ||
340 | &argv[optind - 1]) < 0) | ||
341 | exit(-1); | ||
342 | |||
343 | /* Set the command type and avoid further processing */ | ||
344 | cmd_type = TASKSTATS_CMD_ATTR_PID; | ||
345 | forking = 1; | ||
346 | break; | ||
322 | case 'v': | 347 | case 'v': |
323 | printf("debug on\n"); | 348 | printf("debug on\n"); |
324 | dbg = 1; | 349 | dbg = 1; |
@@ -370,6 +395,15 @@ int main(int argc, char *argv[]) | |||
370 | goto err; | 395 | goto err; |
371 | } | 396 | } |
372 | 397 | ||
398 | /* | ||
399 | * If we forked a child, wait for it to exit. Cannot use waitpid() | ||
400 | * as all the delicious data would be reaped as part of the wait | ||
401 | */ | ||
402 | if (tid && forking) { | ||
403 | int sig_received; | ||
404 | sigwait(&sigset, &sig_received); | ||
405 | } | ||
406 | |||
373 | if (tid) { | 407 | if (tid) { |
374 | rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, | 408 | rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, |
375 | cmd_type, &tid, sizeof(__u32)); | 409 | cmd_type, &tid, sizeof(__u32)); |