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