81a1c4ee18068d995c38538a57bacdb81592f984
[reactos.git] / reactos / lib / crt / signal / signal.c
1 #include "precomp.h"
2
3 #include <signal.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <internal/file.h>
8
9 void _default_handler(int signal);
10
11 //typedef void (*_p_sig_fn_t)(int);
12
13
14 typedef struct _sig_element
15 {
16 int signal;
17 char *signame;
18 __p_sig_fn_t handler;
19 }
20 sig_element;
21
22
23 static sig_element signal_list[] =
24 {
25 { SIGINT, "CTRL+C",SIG_DFL },
26 { SIGILL, "Illegal instruction",SIG_DFL },
27 { SIGFPE, "Floating-point exception",SIG_DFL },
28 { SIGSEGV, "Illegal storage access",SIG_DFL },
29 { SIGTERM, "Termination request",SIG_DFL },
30 { SIGBREAK, "CTRL+BREAK",SIG_DFL },
31 { SIGABRT, "Abnormal termination",SIG_DFL }
32 };
33
34 //int nsignal = 21;
35
36 /*
37 * @implemented
38 */
39 //void ( *signal( int sig, void (__cdecl *func) ( int sig [, int subcode ] )) ) ( int sig );
40
41
42
43
44 __p_sig_fn_t signal(int sig, __p_sig_fn_t func)
45 {
46 __p_sig_fn_t temp;
47 unsigned int i;
48
49 switch (sig)
50 {
51 case SIGINT:
52 case SIGILL:
53 case SIGFPE:
54 case SIGSEGV:
55 case SIGTERM:
56 case SIGBREAK:
57 case SIGABRT:
58 break;
59
60 default:
61 __set_errno(EINVAL);
62 return SIG_ERR;
63 }
64
65 // check with IsBadCodePtr
66 if ( func < (__p_sig_fn_t)4096 && func != SIG_DFL && func != SIG_IGN)
67 {
68 __set_errno(EINVAL);
69 return SIG_ERR;
70 }
71
72 for(i=0; i < sizeof(signal_list)/sizeof(signal_list[0]); i++)
73 {
74 if ( signal_list[i].signal == sig )
75 {
76 temp = signal_list[i].handler;
77 signal_list[i].handler = func;
78 return temp;
79 }
80 }
81
82 /* should be impossible to get here */
83 __set_errno(EINVAL);
84 return SIG_ERR;
85 }
86
87
88 /*
89 * @implemented
90 */
91 int
92 raise(int sig)
93 {
94 __p_sig_fn_t temp = 0;
95 unsigned int i;
96
97 switch (sig)
98 {
99 case SIGINT:
100 case SIGILL:
101 case SIGFPE:
102 case SIGSEGV:
103 case SIGTERM:
104 case SIGBREAK:
105 case SIGABRT:
106 break;
107
108 default:
109 //FIXME: set last err?
110 return -1;
111 }
112
113
114 // if(sig <= 0)
115 // return -1;
116 // if(sig > SIGMAX)
117 // return -1;
118
119 for(i=0;i<sizeof(signal_list)/sizeof(signal_list[0]);i++)
120 {
121 if ( signal_list[i].signal == sig )
122 {
123 temp = signal_list[i].handler;
124 break;
125 }
126 }
127
128 if(temp == SIG_IGN)// || (sig == SIGQUIT && temp == (_p_sig_fn_t)SIG_DFL))
129 return 0; /* Ignore it */
130
131 if(temp == SIG_DFL)
132 _default_handler(sig); /* this does not return */
133 else
134 temp(sig);
135
136 return 0;
137 }
138
139
140
141 void _default_handler(int sig)
142 {
143 _exit(3);
144 }
145
146