|
#include "apue.h" |
|
#include <sys/wait.h> |
|
#include <sys/signal.h> |
|
#include <errno.h> |
|
|
|
void printJobs(); |
|
void addJob(int); |
|
void delJob(); |
|
|
|
void handler(int sig) |
|
{ |
|
sigset_t mask_all, pre_all; |
|
sigfillset(&mask_all); // fill all bits of the mask |
|
pid_t pid; |
|
while ((pid = waitpid(-1, NULL, 0)) > 0) { |
|
sigprocmask(SIG_BLOCK, &mask_all, &pre_all); |
|
printf("del from %d\n", pid); |
|
delJob(pid); |
|
sigprocmask(SIG_UNBLOCK, &pre_all, NULL); |
|
} |
|
if (errno != ECHILD) |
|
printf("waitpid error\n"); |
|
} |
|
|
|
int main(int argc, char **argv) |
|
{ |
|
pid_t pid; |
|
sigset_t mask_all, mask_one, pre_one; |
|
|
|
sigfillset(&mask_all); |
|
sigemptyset(&mask_one); |
|
sigaddset(&mask_one, SIGCHLD); |
|
signal(SIGCHLD, handler); |
|
for (int i = 0; i < 10; ++i) { |
|
sigprocmask(SIG_BLOCK, &mask_one, &pre_one); // block SIGCHLD |
|
if ((pid = fork()) == 0) { |
|
sigprocmask(SIG_SETMASK, &pre_one, NULL); |
|
sleep(1); |
|
execve("/bin/date", argv, NULL); |
|
} |
|
sigprocmask(SIG_BLOCK, &mask_all, NULL); // block all sigals |
|
addJob(pid); |
|
sigprocmask(SIG_SETMASK, &pre_one, NULL); // unblock SIGCHLD |
|
sleep(1); |
|
} |
|
exit(0); |
|
} |
|
|
|
typedef struct Node { |
|
int val; |
|
struct Node *next; |
|
} Node, *pNode; |
|
|
|
pNode phead = NULL, ptail = NULL; |
|
|
|
void printJobs() |
|
{ |
|
pNode pt = phead; |
|
while (pt) { |
|
printf("%d", pt->val); |
|
pt = pt->next; |
|
} |
|
printf("\n"); |
|
} |
|
|
|
void delJob(int pid) |
|
{ |
|
if (ptail) { |
|
pNode pt = phead, pre = NULL; |
|
while (pt && pt->val != pid) { |
|
pre = pt; |
|
pt = pt->next; |
|
} |
|
if (!pt) { |
|
printf("No job %d\n", pid); |
|
return; |
|
} |
|
if (pt == phead) { // only have one node or empty |
|
phead = phead->next ? phead->next : NULL; |
|
free(pt); |
|
ptail = phead ? ptail : NULL; |
|
} else { // have more than one nodes |
|
printf("del %d\n", pt->val); |
|
free(pt); |
|
pre->next = NULL; |
|
ptail = pt == ptail ? pre : ptail; |
|
} |
|
printf("now the list is: "); |
|
printJobs(); |
|
} else { |
|
printf("No job %d\n", pid); |
|
} |
|
} |
|
|
|
void addJob(int pid) |
|
{ |
|
printf("add job %d\n", pid); |
|
pNode pt = malloc(sizeof(Node)); |
|
pt->val = pid; |
|
pt->next = NULL; |
|
if (!phead) { |
|
phead = ptail = pt; |
|
} else { |
|
ptail->next = pt; |
|
ptail = pt; |
|
} |
|
} |