xref: /haiku/src/system/libroot/posix/signal/sigwaitinfo.cpp (revision 3a91fe8d4fbea21cd134cb8f32128e63187da8b6)
124df6592SIngo Weinhold /*
224df6592SIngo Weinhold  * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
324df6592SIngo Weinhold  * Distributed under the terms of the MIT License.
424df6592SIngo Weinhold  */
524df6592SIngo Weinhold 
624df6592SIngo Weinhold 
724df6592SIngo Weinhold #include <signal.h>
824df6592SIngo Weinhold 
90b04cf2fSAugustin Cavalier #include <errno.h>
100b04cf2fSAugustin Cavalier #include <pthread.h>
110b04cf2fSAugustin Cavalier 
120b04cf2fSAugustin Cavalier #include <syscall_utils.h>
130b04cf2fSAugustin Cavalier 
140b04cf2fSAugustin Cavalier #include <errno_private.h>
150b04cf2fSAugustin Cavalier #include <time_private.h>
160b04cf2fSAugustin Cavalier #include <syscalls.h>
170b04cf2fSAugustin Cavalier 
1824df6592SIngo Weinhold 
1924df6592SIngo Weinhold int
sigwaitinfo(const sigset_t * set,siginfo_t * info)2024df6592SIngo Weinhold sigwaitinfo(const sigset_t* set, siginfo_t* info)
2124df6592SIngo Weinhold {
2224df6592SIngo Weinhold 	return sigtimedwait(set, info, NULL);
2324df6592SIngo Weinhold }
240b04cf2fSAugustin Cavalier 
250b04cf2fSAugustin Cavalier 
260b04cf2fSAugustin Cavalier int
sigtimedwait(const sigset_t * set,siginfo_t * info,const struct timespec * timeout)270b04cf2fSAugustin Cavalier sigtimedwait(const sigset_t* set, siginfo_t* info,
280b04cf2fSAugustin Cavalier 	const struct timespec* timeout)
290b04cf2fSAugustin Cavalier {
300b04cf2fSAugustin Cavalier 	// make info non-NULL to simplify things
310b04cf2fSAugustin Cavalier 	siginfo_t stackInfo;
320b04cf2fSAugustin Cavalier 	if (info == NULL)
330b04cf2fSAugustin Cavalier 		info = &stackInfo;
340b04cf2fSAugustin Cavalier 
350b04cf2fSAugustin Cavalier 	// translate the timeout
360b04cf2fSAugustin Cavalier 	uint32 flags;
370b04cf2fSAugustin Cavalier 	bigtime_t timeoutMicros = 0;
38*3a91fe8dSAugustin Cavalier 	bool invalidTime = false;
390b04cf2fSAugustin Cavalier 	if (timeout != NULL) {
400b04cf2fSAugustin Cavalier 		if (!timespec_to_bigtime(*timeout, timeoutMicros))
41*3a91fe8dSAugustin Cavalier 			invalidTime = true;
42*3a91fe8dSAugustin Cavalier 		flags = B_RELATIVE_TIMEOUT;
430b04cf2fSAugustin Cavalier 	} else {
440b04cf2fSAugustin Cavalier 		flags = 0;
450b04cf2fSAugustin Cavalier 		timeoutMicros = 0;
460b04cf2fSAugustin Cavalier 	}
470b04cf2fSAugustin Cavalier 
480b04cf2fSAugustin Cavalier 	status_t error = _kern_sigwait(set, info, flags, timeoutMicros);
490b04cf2fSAugustin Cavalier 
500b04cf2fSAugustin Cavalier 	pthread_testcancel();
510b04cf2fSAugustin Cavalier 
52*3a91fe8dSAugustin Cavalier 	if (error != B_OK && invalidTime)
53*3a91fe8dSAugustin Cavalier 		error = EINVAL;
54*3a91fe8dSAugustin Cavalier 
550b04cf2fSAugustin Cavalier 	if (error != B_OK)
560b04cf2fSAugustin Cavalier 		RETURN_AND_SET_ERRNO(error);
570b04cf2fSAugustin Cavalier 
580b04cf2fSAugustin Cavalier 	return info->si_signo;
590b04cf2fSAugustin Cavalier }
60