ef261ab89b4a70be93777b2f67b8727fbd4b75f5
[lunaix-os.git] / lunaix-os / uprog / signal_demo.c
1 #include <signal.h>
2
3 void
4 sigchild_handler(int signum)
5 {
6     printf("SIGCHLD received\n");
7 }
8
9 void
10 sigsegv_handler(int signum)
11 {
12     pid_t pid = getpid();
13     printf("SIGSEGV received on process %d\n", pid);
14     _exit(signum);
15 }
16
17 void
18 sigalrm_handler(int signum)
19 {
20     pid_t pid = getpid();
21     printf("I, pid %d, have received an alarm!\n", pid);
22 }
23
24 void
25 main()
26 {
27     signal(SIGCHLD, sigchild_handler);
28     signal(SIGSEGV, sigsegv_handler);
29     signal(SIGALRM, sigalrm_handler);
30
31     alarm(5);
32
33     int status;
34     pid_t p = 0;
35
36     printf("Child sleep 3s, parent pause.\n");
37     if (!fork()) {
38         sleep(3);
39         _exit(0);
40     }
41
42     pause();
43
44     printf("Parent resumed on SIGCHILD\n");
45
46     for (int i = 0; i < 5; i++) {
47         pid_t pid = 0;
48         if (!(pid = fork())) {
49             signal(SIGSEGV, sigsegv_handler);
50             sleep(i);
51             if (i == 3) {
52                 i = *(int*)0xdeadc0de; // seg fault!
53             }
54             printf("%d\n", i);
55             _exit(0);
56         }
57         printf("Forked %d\n", pid);
58     }
59
60     while ((p = wait(&status)) >= 0) {
61         short code = WEXITSTATUS(status);
62         if (WIFSIGNALED(status)) {
63             printf("Process %d terminated by signal, exit_code: %d\n", p, code);
64         } else if (WIFEXITED(status)) {
65             printf("Process %d exited with code %d\n", p, code);
66         } else {
67             printf("Process %d aborted with code %d\n", p, code);
68         }
69     }
70
71     printf("done\n");
72 }