1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill/*
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * This file and its contents are supplied under the terms of the
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * Common Development and Distribution License ("CDDL"), version 1.0.
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * You may only use this file in accordance with the terms of version
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * 1.0 of the CDDL.
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill *
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * A full copy of the text of the CDDL should have accompanied this
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * source. A copy of the CDDL is also available via the Internet at
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * http://www.illumos.org/license/CDDL.
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill */
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill/*
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill * Copyright (c) 2015, Joyent, Inc. All rights reserved.
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill */
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill#include <sys/eventfd.h>
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill#include <sys/stat.h>
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill#include <unistd.h>
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill#include <errno.h>
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill#include <fcntl.h>
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrillint
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrilleventfd(unsigned int initval, int flags)
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill{
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill int oflags = O_RDWR;
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill uint64_t val = initval;
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill int fd;
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill if (flags & ~(EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE)) {
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill errno = EINVAL;
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill return (-1);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill }
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill if (flags & EFD_NONBLOCK)
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill oflags |= O_NONBLOCK;
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill if (flags & EFD_CLOEXEC)
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill oflags |= O_CLOEXEC;
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill if ((fd = open("/dev/eventfd", oflags)) < 0)
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill return (-1);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill if ((flags & EFD_SEMAPHORE) &&
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill ioctl(fd, EVENTFDIOC_SEMAPHORE, 0) != 0) {
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill (void) close(fd);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill return (-1);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill }
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill if (write(fd, &val, sizeof (val)) < sizeof (val)) {
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill (void) close(fd);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill return (-1);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill }
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill return (fd);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill}
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrillint
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrilleventfd_read(int fd, eventfd_t *valp)
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill{
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill return (read(fd, valp, sizeof (*valp)) < sizeof (*valp) ? -1 : 0);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill}
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrillint
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrilleventfd_write(int fd, eventfd_t val)
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill{
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill return (write(fd, &val, sizeof (val)) < sizeof (val) ? -1 : 0);
1767006bb066ef500b90b432fba79d63d0d09b36Bryan Cantrill}