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)); |
