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 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