1 /*
2  * Copyright (c) 2009 Marko Kreen
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /** @file
18  * Signals compat.
19  *
20  * general
21  * - sigaction() -> signal()
22  *
23  * win32:
24  * - SIGALRM, alarm(), signal(SIGALRM), sigaction(SIGALRM)
25  * - kill(pid, 0)
26  */
27 #ifndef _USUAL_SIGNAL_H_
28 #define _USUAL_SIGNAL_H_
29 
30 #include <usual/base.h>
31 
32 #include <signal.h>
33 
34 /*
35  * Compat sigval, detect based on siginfo_t.si_code.
36  */
37 
38 #if !defined(SI_QUEUE) && !defined(HAVE_SIGQUEUE)
39 union sigval {
40 	int sival_int;
41 	void *sival_ptr;
42 };
43 #endif
44 
45 /*
46  * Compat sigevent
47  */
48 
49 #ifndef SIGEV_NONE
50 #define SIGEV_NONE 0
51 #define SIGEV_SIGNAL 1
52 #define SIGEV_THREAD 2
53 struct sigevent {
54 	int sigev_notify;
55 	int sigev_signo;
56 	union sigval sigev_value;
57 	void (*sigev_notify_function)(union sigval);
58 
59 };
60 #endif
61 
62 /*
63  * Compat sigaction()
64  */
65 
66 #ifndef HAVE_SIGACTION
67 #define SA_SIGINFO 1
68 #define SA_RESTART 2
69 typedef struct siginfo_t siginfo_t;
70 struct sigaction {
71 	union {
72 		void     (*sa_handler)(int);
73 		void     (*sa_sigaction)(int, siginfo_t *, void *);
74 	};
75 	int sa_flags;
76 	int sa_mask;
77 };
78 #define sigemptyset(s)
79 #define sigfillset(s)
80 #define sigaddset(s, sig)
81 #define sigdelset(s, sig)
82 #define sigaction(a,b,c) compat_sigaction(a,b,c)
83 int sigaction(int sig, const struct sigaction *sa, struct sigaction *old);
84 #endif
85 
86 /*
87  * win32 compat:
88  * kill(), alarm, SIGALRM
89  */
90 
91 #ifdef WIN32
92 
93 #define SIGALRM 1023
94 #define SIGBUS 1022
95 unsigned alarm(unsigned);
96 
97 int kill(int pid, int sig);
98 
99 typedef void (*_sighandler_t)(int);
100 
wrap_signal(int sig,_sighandler_t func)101 static inline _sighandler_t wrap_signal(int sig, _sighandler_t func)
102 {
103 	/* sigaction has custom handling for SIGALRM */
104 	if (sig == SIGALRM) {
105 		struct sigaction sa, oldsa;
106 		sa.sa_handler = func;
107 		sa.sa_flags = sa.sa_mask = 0;
108 		sigaction(SIGALRM, &sa, &oldsa);
109 		return oldsa.sa_handler;
110 	} else if (sig == SIGBUS) {
111 		return NULL;
112 	}
113 	return signal(sig, func);
114 }
115 #define signal(a,b) wrap_signal(a,b)
116 #endif
117 
118 #endif
119