xref: /haiku/src/system/libroot/posix/signal/sigwaitinfo.cpp (revision 344ded80d400028c8f561b4b876257b94c12db4a)
1 /*
2  * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <signal.h>
8 
9 #include <errno.h>
10 #include <pthread.h>
11 
12 #include <syscall_utils.h>
13 
14 #include <errno_private.h>
15 #include <time_private.h>
16 #include <syscalls.h>
17 
18 
19 int
20 sigwaitinfo(const sigset_t* set, siginfo_t* info)
21 {
22 	return sigtimedwait(set, info, NULL);
23 }
24 
25 
26 int
27 sigtimedwait(const sigset_t* set, siginfo_t* info,
28 	const struct timespec* timeout)
29 {
30 	// make info non-NULL to simplify things
31 	siginfo_t stackInfo;
32 	if (info == NULL)
33 		info = &stackInfo;
34 
35 	// translate the timeout
36 	uint32 flags;
37 	bigtime_t timeoutMicros = 0;
38 	bool invalidTime = false;
39 	if (timeout != NULL) {
40 		if (!timespec_to_bigtime(*timeout, timeoutMicros))
41 			invalidTime = true;
42 		flags = B_RELATIVE_TIMEOUT;
43 	} else {
44 		flags = 0;
45 		timeoutMicros = 0;
46 	}
47 
48 	status_t error = _kern_sigwait(set, info, flags, timeoutMicros);
49 
50 	pthread_testcancel();
51 
52 	if (error != B_OK && invalidTime)
53 		error = EINVAL;
54 
55 	if (error != B_OK)
56 		RETURN_AND_SET_ERRNO(error);
57 
58 	return info->si_signo;
59 }
60