diff options
author | Bryan Cantrill <bryan@joyent.com> | 2015-02-14 16:55:35 -0800 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2015-10-16 11:59:14 -0700 |
commit | a5eb7107f06a6e23e8e77e8d3a84c1ff90a73ac6 (patch) | |
tree | 70fac1fa3fb719f5145ff6db721af2c343faa4f2 /usr/src/lib/libc | |
parent | 7509ca605713ac7f244b0e812b1712dd25f04da1 (diff) | |
download | illumos-gate-a5eb7107f06a6e23e8e77e8d3a84c1ff90a73ac6.tar.gz |
5640 want epoll support
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/amd64/Makefile | 1 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/Makefile.com | 1 | ||||
-rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 9 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/epoll.c | 207 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/Makefile.com | 1 | ||||
-rw-r--r-- | usr/src/lib/libc/sparcv9/Makefile.com | 1 |
6 files changed, 220 insertions, 0 deletions
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index 0c1421bbf2..b5e54b19fa 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -863,6 +863,7 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ exacctsys.o \ execl.o \ execle.o \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 9a76280c0a..d7e77502f2 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -903,6 +903,7 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ eventfd.o \ exacctsys.o \ execl.o \ diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 0b683fc923..017c7c31bc 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -93,6 +93,15 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.15 { # epoll(3C) + protected: + epoll_create; + epoll_create1; + epoll_ctl; + epoll_wait; + epoll_pwait; +} ILLUMOS_0.14; + SYMBOL_VERSION ILLUMOS_0.14 { # strerror_l protected: strerror_l; diff --git a/usr/src/lib/libc/port/sys/epoll.c b/usr/src/lib/libc/port/sys/epoll.c new file mode 100644 index 0000000000..93379b583e --- /dev/null +++ b/usr/src/lib/libc/port/sys/epoll.c @@ -0,0 +1,207 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014, Joyent, Inc. All rights reserved. + */ + +#include <sys/types.h> +#include <sys/epoll.h> +#include <sys/devpoll.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <poll.h> + +/* + * Events that match their epoll(7) equivalents. + */ +#if EPOLLIN != POLLIN +#error value of EPOLLIN does not match value of POLLIN +#endif + +#if EPOLLPRI != POLLPRI +#error value of EPOLLPRI does not match value of POLLPRI +#endif + +#if EPOLLOUT != POLLOUT +#error value of EPOLLOUT does not match value of POLLOUT +#endif + +#if EPOLLRDNORM != POLLRDNORM +#error value of EPOLLRDNORM does not match value of POLLRDNORM +#endif + +#if EPOLLRDBAND != POLLRDBAND +#error value of EPOLLRDBAND does not match value of POLLRDBAND +#endif + +#if EPOLLERR != POLLERR +#error value of EPOLLERR does not match value of POLLERR +#endif + +#if EPOLLHUP != POLLHUP +#error value of EPOLLHUP does not match value of POLLHUP +#endif + +/* + * Events that we ignore entirely. They can be set in events, but they will + * never be returned. + */ +#define EPOLLIGNORED (EPOLLMSG | EPOLLWAKEUP) + +/* + * Events that we swizzle into other bit positions. + */ +#define EPOLLSWIZZLED \ + (EPOLLRDHUP | EPOLLONESHOT | EPOLLET | EPOLLWRBAND | EPOLLWRNORM) + +int +epoll_create(int size) +{ + int fd; + + /* + * From the epoll_create() man page: "Since Linux 2.6.8, the size + * argument is ignored, but must be greater than zero." You keep using + * that word "ignored"... + */ + if (size <= 0) { + errno = EINVAL; + return (-1); + } + + if ((fd = open("/dev/poll", O_RDWR)) == -1) + return (-1); + + if (ioctl(fd, DP_EPOLLCOMPAT, 0) == -1) { + (void) close(fd); + return (-1); + } + + return (fd); +} + +int +epoll_create1(int flags) +{ + int fd, oflags = O_RDWR; + + if (flags & EPOLL_CLOEXEC) + oflags |= O_CLOEXEC; + + if ((fd = open("/dev/poll", oflags)) == -1) + return (-1); + + if (ioctl(fd, DP_EPOLLCOMPAT, 0) == -1) { + (void) close(fd); + return (-1); + } + + return (fd); +} + +int +epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + dvpoll_epollfd_t epoll[2]; + uint32_t events, ev = 0; + int i = 0; + + epoll[i].dpep_pollfd.fd = fd; + + switch (op) { + case EPOLL_CTL_DEL: + ev = POLLREMOVE; + break; + + case EPOLL_CTL_MOD: + /* + * In the modify case, we pass down two events: one to + * remove the event and another to add it back. + */ + epoll[i++].dpep_pollfd.events = POLLREMOVE; + epoll[i].dpep_pollfd.fd = fd; + /* FALLTHROUGH */ + + case EPOLL_CTL_ADD: + /* + * Mask off the events that we ignore, and then swizzle the + * events for which our values differ from their epoll(7) + * equivalents. + */ + events = event->events; + ev = events & ~(EPOLLIGNORED | EPOLLSWIZZLED); + + if (events & EPOLLRDHUP) + ev |= POLLRDHUP; + + if (events & EPOLLET) + ev |= POLLET; + + if (events & EPOLLONESHOT) + ev |= POLLONESHOT; + + if (events & EPOLLWRNORM) + ev |= POLLWRNORM; + + if (events & EPOLLWRBAND) + ev |= POLLWRBAND; + + epoll[i].dpep_data = event->data.u64; + break; + + default: + errno = EOPNOTSUPP; + return (-1); + } + + epoll[i].dpep_pollfd.events = ev; + + return (write(epfd, epoll, sizeof (epoll[0]) * (i + 1)) == -1 ? -1 : 0); +} + +int +epoll_wait(int epfd, struct epoll_event *events, + int maxevents, int timeout) +{ + struct dvpoll arg; + + if (maxevents <= 0) { + errno = EINVAL; + return (-1); + } + + arg.dp_nfds = maxevents; + arg.dp_timeout = timeout; + arg.dp_fds = (pollfd_t *)events; + + return (ioctl(epfd, DP_POLL, &arg)); +} + +int +epoll_pwait(int epfd, struct epoll_event *events, + int maxevents, int timeout, const sigset_t *sigmask) +{ + struct dvpoll arg; + + if (maxevents <= 0) { + errno = EINVAL; + return (-1); + } + + arg.dp_nfds = maxevents; + arg.dp_timeout = timeout; + arg.dp_fds = (pollfd_t *)events; + arg.dp_setp = (sigset_t *)sigmask; + + return (ioctl(epfd, DP_PPOLL, &arg)); +} diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index 3856c5332c..dc965fe6ac 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -937,6 +937,7 @@ PORTSYS= \ chmod.o \ chown.o \ corectl.o \ + epoll.o \ eventfd.o \ exacctsys.o \ execl.o \ diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index 1a65ab7680..415aaf2be2 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -882,6 +882,7 @@ PORTSYS= \ chown.o \ corectl.o \ eventfd.o \ + epoll.o \ exacctsys.o \ execl.o \ execle.o \ |