xref: /illumos-gate/usr/src/lib/libc/port/sys/signalfd.c (revision 3d729aec)
1*3d729aecSJerry Jelinek /*
2*3d729aecSJerry Jelinek  * This file and its contents are supplied under the terms of the
3*3d729aecSJerry Jelinek  * Common Development and Distribution License ("CDDL"), version 1.0.
4*3d729aecSJerry Jelinek  * You may only use this file in accordance with the terms of version
5*3d729aecSJerry Jelinek  * 1.0 of the CDDL.
6*3d729aecSJerry Jelinek  *
7*3d729aecSJerry Jelinek  * A full copy of the text of the CDDL should have accompanied this
8*3d729aecSJerry Jelinek  * source.  A copy of the CDDL is also available via the Internet at
9*3d729aecSJerry Jelinek  * http://www.illumos.org/license/CDDL.
10*3d729aecSJerry Jelinek  */
11*3d729aecSJerry Jelinek 
12*3d729aecSJerry Jelinek /*
13*3d729aecSJerry Jelinek  * Copyright 2015, Joyent, Inc.
14*3d729aecSJerry Jelinek  */
15*3d729aecSJerry Jelinek 
16*3d729aecSJerry Jelinek #include <sys/signalfd.h>
17*3d729aecSJerry Jelinek #include <sys/stat.h>
18*3d729aecSJerry Jelinek #include <unistd.h>
19*3d729aecSJerry Jelinek #include <errno.h>
20*3d729aecSJerry Jelinek #include <fcntl.h>
21*3d729aecSJerry Jelinek 
22*3d729aecSJerry Jelinek int
signalfd(int fd,const sigset_t * mask,int flags)23*3d729aecSJerry Jelinek signalfd(int fd, const sigset_t *mask, int flags)
24*3d729aecSJerry Jelinek {
25*3d729aecSJerry Jelinek 	int origfd = fd;
26*3d729aecSJerry Jelinek 
27*3d729aecSJerry Jelinek 	if (fd == -1) {
28*3d729aecSJerry Jelinek 		int oflags = O_RDONLY;
29*3d729aecSJerry Jelinek 
30*3d729aecSJerry Jelinek 		if (flags & ~(SFD_NONBLOCK | SFD_CLOEXEC)) {
31*3d729aecSJerry Jelinek 			errno = EINVAL;
32*3d729aecSJerry Jelinek 			return (-1);
33*3d729aecSJerry Jelinek 		}
34*3d729aecSJerry Jelinek 
35*3d729aecSJerry Jelinek 		if (flags & SFD_NONBLOCK)
36*3d729aecSJerry Jelinek 			oflags |= O_NONBLOCK;
37*3d729aecSJerry Jelinek 
38*3d729aecSJerry Jelinek 		if (flags & SFD_CLOEXEC)
39*3d729aecSJerry Jelinek 			oflags |= O_CLOEXEC;
40*3d729aecSJerry Jelinek 
41*3d729aecSJerry Jelinek 		if ((fd = open("/dev/signalfd", oflags)) < 0)
42*3d729aecSJerry Jelinek 			return (-1);
43*3d729aecSJerry Jelinek 	}
44*3d729aecSJerry Jelinek 
45*3d729aecSJerry Jelinek 	if (ioctl(fd, SIGNALFDIOC_MASK, mask) != 0) {
46*3d729aecSJerry Jelinek 		if (origfd == -1) {
47*3d729aecSJerry Jelinek 			int old = errno;
48*3d729aecSJerry Jelinek 			(void) close(fd);
49*3d729aecSJerry Jelinek 			errno = old;
50*3d729aecSJerry Jelinek 		}
51*3d729aecSJerry Jelinek 		/*
52*3d729aecSJerry Jelinek 		 * Trying to modify an existing sigfd so if this failed
53*3d729aecSJerry Jelinek 		 * it's because it's not a valid fd or not a sigfd. ioctl
54*3d729aecSJerry Jelinek 		 * returns the correct errno for these cases.
55*3d729aecSJerry Jelinek 		 */
56*3d729aecSJerry Jelinek 		return (-1);
57*3d729aecSJerry Jelinek 	}
58*3d729aecSJerry Jelinek 
59*3d729aecSJerry Jelinek 	return (fd);
60*3d729aecSJerry Jelinek }
61