1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
14 */
15
16 #include <sys/types.h>
17 #include <sys/epoll.h>
18 #include <sys/devpoll.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <poll.h>
23
24 /*
25 * Events that match their epoll(7) equivalents.
26 */
27 #if EPOLLIN != POLLIN
28 #error value of EPOLLIN does not match value of POLLIN
29 #endif
30
31 #if EPOLLPRI != POLLPRI
32 #error value of EPOLLPRI does not match value of POLLPRI
33 #endif
97
98 if (flags & EPOLL_CLOEXEC)
99 oflags |= O_CLOEXEC;
100
101 if ((fd = open("/dev/poll", oflags)) == -1)
102 return (-1);
103
104 if (ioctl(fd, DP_EPOLLCOMPAT, 0) == -1) {
105 (void) close(fd);
106 return (-1);
107 }
108
109 return (fd);
110 }
111
112 int
113 epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
114 {
115 dvpoll_epollfd_t epoll[2];
116 uint32_t events, ev = 0;
117 int i = 0;
118
119 epoll[i].dpep_pollfd.fd = fd;
120
121 switch (op) {
122 case EPOLL_CTL_DEL:
123 ev = POLLREMOVE;
124 break;
125
126 case EPOLL_CTL_MOD:
127 /*
128 * In the modify case, we pass down two events: one to
129 * remove the event and another to add it back.
130 */
131 epoll[i++].dpep_pollfd.events = POLLREMOVE;
132 epoll[i].dpep_pollfd.fd = fd;
133 /* FALLTHROUGH */
134
135 case EPOLL_CTL_ADD:
136 /*
137 * Mask off the events that we ignore, and then swizzle the
148 ev |= POLLET;
149
150 if (events & EPOLLONESHOT)
151 ev |= POLLONESHOT;
152
153 if (events & EPOLLWRNORM)
154 ev |= POLLWRNORM;
155
156 if (events & EPOLLWRBAND)
157 ev |= POLLWRBAND;
158
159 epoll[i].dpep_data = event->data.u64;
160 break;
161
162 default:
163 errno = EOPNOTSUPP;
164 return (-1);
165 }
166
167 epoll[i].dpep_pollfd.events = ev;
168
169 return (write(epfd, epoll, sizeof (epoll[0]) * (i + 1)) == -1 ? -1 : 0);
170 }
171
172 int
173 epoll_wait(int epfd, struct epoll_event *events,
174 int maxevents, int timeout)
175 {
176 struct dvpoll arg;
177
178 if (maxevents <= 0) {
179 errno = EINVAL;
180 return (-1);
181 }
182
183 arg.dp_nfds = maxevents;
184 arg.dp_timeout = timeout;
185 arg.dp_fds = (pollfd_t *)events;
186
187 return (ioctl(epfd, DP_POLL, &arg));
188 }
189
|
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2016 Joyent, Inc.
14 */
15
16 #include <sys/types.h>
17 #include <sys/epoll.h>
18 #include <sys/devpoll.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <poll.h>
23
24 /*
25 * Events that match their epoll(7) equivalents.
26 */
27 #if EPOLLIN != POLLIN
28 #error value of EPOLLIN does not match value of POLLIN
29 #endif
30
31 #if EPOLLPRI != POLLPRI
32 #error value of EPOLLPRI does not match value of POLLPRI
33 #endif
97
98 if (flags & EPOLL_CLOEXEC)
99 oflags |= O_CLOEXEC;
100
101 if ((fd = open("/dev/poll", oflags)) == -1)
102 return (-1);
103
104 if (ioctl(fd, DP_EPOLLCOMPAT, 0) == -1) {
105 (void) close(fd);
106 return (-1);
107 }
108
109 return (fd);
110 }
111
112 int
113 epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
114 {
115 dvpoll_epollfd_t epoll[2];
116 uint32_t events, ev = 0;
117 int i = 0, res;
118
119 epoll[i].dpep_pollfd.fd = fd;
120
121 switch (op) {
122 case EPOLL_CTL_DEL:
123 ev = POLLREMOVE;
124 break;
125
126 case EPOLL_CTL_MOD:
127 /*
128 * In the modify case, we pass down two events: one to
129 * remove the event and another to add it back.
130 */
131 epoll[i++].dpep_pollfd.events = POLLREMOVE;
132 epoll[i].dpep_pollfd.fd = fd;
133 /* FALLTHROUGH */
134
135 case EPOLL_CTL_ADD:
136 /*
137 * Mask off the events that we ignore, and then swizzle the
148 ev |= POLLET;
149
150 if (events & EPOLLONESHOT)
151 ev |= POLLONESHOT;
152
153 if (events & EPOLLWRNORM)
154 ev |= POLLWRNORM;
155
156 if (events & EPOLLWRBAND)
157 ev |= POLLWRBAND;
158
159 epoll[i].dpep_data = event->data.u64;
160 break;
161
162 default:
163 errno = EOPNOTSUPP;
164 return (-1);
165 }
166
167 epoll[i].dpep_pollfd.events = ev;
168 retry:
169 res = write(epfd, epoll, sizeof (epoll[0]) * (i + 1));
170
171 if (res == -1) {
172 if (errno == EINTR) {
173 /*
174 * Linux does not document EINTR as an allowed error
175 * for epoll_ctl. The write must be retried if it is
176 * not done automatically via SA_RESTART.
177 */
178 goto retry;
179 }
180 if (errno == ELOOP) {
181 /*
182 * Convert the specific /dev/poll error about an fd
183 * loop into what is expected from the Linux epoll
184 * interface.
185 */
186 errno = EINVAL;
187 }
188 return (-1);
189 }
190 return (0);
191 }
192
193 int
194 epoll_wait(int epfd, struct epoll_event *events,
195 int maxevents, int timeout)
196 {
197 struct dvpoll arg;
198
199 if (maxevents <= 0) {
200 errno = EINVAL;
201 return (-1);
202 }
203
204 arg.dp_nfds = maxevents;
205 arg.dp_timeout = timeout;
206 arg.dp_fds = (pollfd_t *)events;
207
208 return (ioctl(epfd, DP_POLL, &arg));
209 }
210
|