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