xref: /illumos-gate/usr/src/lib/libc/port/sys/eventfd.c (revision d7159b37699523966f5e7af69b1bd84e2a084fa4)
11767006bSBryan Cantrill /*
21767006bSBryan Cantrill  * This file and its contents are supplied under the terms of the
31767006bSBryan Cantrill  * Common Development and Distribution License ("CDDL"), version 1.0.
41767006bSBryan Cantrill  * You may only use this file in accordance with the terms of version
51767006bSBryan Cantrill  * 1.0 of the CDDL.
61767006bSBryan Cantrill  *
71767006bSBryan Cantrill  * A full copy of the text of the CDDL should have accompanied this
81767006bSBryan Cantrill  * source.  A copy of the CDDL is also available via the Internet at
91767006bSBryan Cantrill  * http://www.illumos.org/license/CDDL.
101767006bSBryan Cantrill  */
111767006bSBryan Cantrill 
121767006bSBryan Cantrill /*
131767006bSBryan Cantrill  * Copyright (c) 2015, Joyent, Inc.  All rights reserved.
14*d7159b37SAndy Fiddaman  * Copyright 2021 OmniOS Community Edition (OmniOSce) Association.
151767006bSBryan Cantrill  */
161767006bSBryan Cantrill 
171767006bSBryan Cantrill #include <sys/eventfd.h>
181767006bSBryan Cantrill #include <sys/stat.h>
191767006bSBryan Cantrill #include <unistd.h>
201767006bSBryan Cantrill #include <errno.h>
211767006bSBryan Cantrill #include <fcntl.h>
221767006bSBryan Cantrill 
231767006bSBryan Cantrill int
eventfd(unsigned int initval,int flags)241767006bSBryan Cantrill eventfd(unsigned int initval, int flags)
251767006bSBryan Cantrill {
261767006bSBryan Cantrill 	int oflags = O_RDWR;
271767006bSBryan Cantrill 	uint64_t val = initval;
281767006bSBryan Cantrill 	int fd;
291767006bSBryan Cantrill 
301767006bSBryan Cantrill 	if (flags & ~(EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE)) {
311767006bSBryan Cantrill 		errno = EINVAL;
321767006bSBryan Cantrill 		return (-1);
331767006bSBryan Cantrill 	}
341767006bSBryan Cantrill 
351767006bSBryan Cantrill 	if (flags & EFD_NONBLOCK)
361767006bSBryan Cantrill 		oflags |= O_NONBLOCK;
371767006bSBryan Cantrill 
381767006bSBryan Cantrill 	if (flags & EFD_CLOEXEC)
391767006bSBryan Cantrill 		oflags |= O_CLOEXEC;
401767006bSBryan Cantrill 
411767006bSBryan Cantrill 	if ((fd = open("/dev/eventfd", oflags)) < 0)
421767006bSBryan Cantrill 		return (-1);
431767006bSBryan Cantrill 
441767006bSBryan Cantrill 	if ((flags & EFD_SEMAPHORE) &&
451767006bSBryan Cantrill 	    ioctl(fd, EVENTFDIOC_SEMAPHORE, 0) != 0) {
461767006bSBryan Cantrill 		(void) close(fd);
471767006bSBryan Cantrill 		return (-1);
481767006bSBryan Cantrill 	}
491767006bSBryan Cantrill 
501767006bSBryan Cantrill 	if (write(fd, &val, sizeof (val)) < sizeof (val)) {
511767006bSBryan Cantrill 		(void) close(fd);
521767006bSBryan Cantrill 		return (-1);
531767006bSBryan Cantrill 	}
541767006bSBryan Cantrill 
551767006bSBryan Cantrill 	return (fd);
561767006bSBryan Cantrill }
571767006bSBryan Cantrill 
581767006bSBryan Cantrill int
eventfd_read(int fd,eventfd_t * valp)591767006bSBryan Cantrill eventfd_read(int fd, eventfd_t *valp)
601767006bSBryan Cantrill {
61*d7159b37SAndy Fiddaman 	ssize_t ret = read(fd, valp, sizeof (*valp));
62*d7159b37SAndy Fiddaman 	if (ret == -1 || (size_t)ret < sizeof (*valp))
63*d7159b37SAndy Fiddaman 		return (-1);
64*d7159b37SAndy Fiddaman 	return (0);
651767006bSBryan Cantrill }
661767006bSBryan Cantrill 
671767006bSBryan Cantrill int
eventfd_write(int fd,eventfd_t val)681767006bSBryan Cantrill eventfd_write(int fd, eventfd_t val)
691767006bSBryan Cantrill {
70*d7159b37SAndy Fiddaman 	ssize_t ret = write(fd, &val, sizeof (val));
71*d7159b37SAndy Fiddaman 	if (ret == -1 || (size_t)ret < sizeof (val))
72*d7159b37SAndy Fiddaman 		return (-1);
73*d7159b37SAndy Fiddaman 	return (0);
741767006bSBryan Cantrill }
75