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