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