1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
#include "csapp.h"
static pid_t spawn(void (*fn)(void)) {
pid_t pid = Fork();
if (pid == 0) {
fn();
printf("(%d) I'm done!\n", getpid());
exit(EXIT_SUCCESS);
}
return pid;
}
static void grandchild(void) {
printf("(%d) Waiting for signal!\n", getpid());
pause();
printf("(%d) Got the signal!\n", getpid());
}
static void child(void) {
pid_t pid;
setpgid(0, 0);
pid = spawn(grandchild);
printf("(%d) Grandchild (%d) spawned!\n", getpid(), pid);
}
/* Runs command "ps -o pid,ppid,pgrp,stat,cmd" using execve(2). */
static void ps(void) {
pid_t pid = Fork();
if (pid == 0) {
if (execlp("ps", "ps", "-o", "pid,ppid,pgrp,stat,cmd", NULL) < 0) {
fprintf(stderr, "Exec error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}
waitpid(pid, NULL, 0);
}
int main(void) {
/* TODO: Make yourself a reaper. */
#ifdef LINUX
Prctl(PR_SET_CHILD_SUBREAPER, 1);
#endif
printf("(%d) I'm a reaper now!\n", getpid());
pid_t pid, pgrp;
int status;
/* TODO: Start child and grandchild, then kill child!
* Remember that you need to kill all subprocesses before quit. */
pid = spawn(child);
pgrp = pid;
waitpid(pid, &status, 0);
ps();
Kill(-pgrp, SIGINT);
pid = wait(&status);
printf("Reaped the grandchild (%d), exit code: %d\n", pid, status);
return EXIT_SUCCESS;
}
|