3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek/*
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * This file and its contents are supplied under the terms of the
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * Common Development and Distribution License ("CDDL"), version 1.0.
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * You may only use this file in accordance with the terms of version
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * 1.0 of the CDDL.
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek *
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * A full copy of the text of the CDDL should have accompanied this
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * source. A copy of the CDDL is also available via the Internet at
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * http://www.illumos.org/license/CDDL.
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek */
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek/*
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * Copyright 2015, Joyent, Inc.
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek */
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek#include <sys/signalfd.h>
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek#include <sys/stat.h>
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek#include <unistd.h>
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek#include <errno.h>
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek#include <fcntl.h>
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinekint
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelineksignalfd(int fd, const sigset_t *mask, int flags)
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek{
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek int origfd = fd;
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek if (fd == -1) {
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek int oflags = O_RDONLY;
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek if (flags & ~(SFD_NONBLOCK | SFD_CLOEXEC)) {
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek errno = EINVAL;
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek return (-1);
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek }
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek if (flags & SFD_NONBLOCK)
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek oflags |= O_NONBLOCK;
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek if (flags & SFD_CLOEXEC)
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek oflags |= O_CLOEXEC;
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek if ((fd = open("/dev/signalfd", oflags)) < 0)
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek return (-1);
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek }
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek if (ioctl(fd, SIGNALFDIOC_MASK, mask) != 0) {
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek if (origfd == -1) {
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek int old = errno;
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek (void) close(fd);
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek errno = old;
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek }
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek /*
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * Trying to modify an existing sigfd so if this failed
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * it's because it's not a valid fd or not a sigfd. ioctl
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek * returns the correct errno for these cases.
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek */
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek return (-1);
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek }
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek return (fd);
3d729aecc03ea6ebb9bd5d56b8dccd24f57daa41Jerry Jelinek}