[core] consolidate duplicated read-to-close code
[lighttpd.git] / src / fdevent_solaris_devpoll.c
blobc3b8f6e9b38b32f84aebe3f73183ab3a2cdcecf8
1 #include "first.h"
3 #include "fdevent.h"
4 #include "buffer.h"
5 #include "log.h"
7 #include <sys/types.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <signal.h>
15 #include <fcntl.h>
17 #ifdef USE_SOLARIS_DEVPOLL
19 # include <sys/devpoll.h>
21 static void fdevent_solaris_devpoll_free(fdevents *ev) {
22 free(ev->devpollfds);
23 close(ev->devpoll_fd);
26 /* return -1 is fine here */
28 static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) {
29 struct pollfd pfd;
31 if (fde_ndx < 0) return -1;
33 pfd.fd = fd;
34 pfd.events = POLLREMOVE;
35 pfd.revents = 0;
37 if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
38 log_error_write(ev->srv, __FILE__, __LINE__, "S(D, S)",
39 "(del) write failed: ", fd, strerror(errno));
41 return -1;
44 return -1;
47 static int fdevent_solaris_devpoll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
48 struct pollfd pfd;
49 int add = 0;
51 int pevents = 0;
52 if (events & FDEVENT_IN) pevents |= POLLIN;
53 if (events & FDEVENT_OUT) pevents |= POLLOUT;
55 if (fde_ndx == -1) add = 1;
57 pfd.fd = fd;
58 pfd.events = pevents;
59 pfd.revents = 0;
61 if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
62 log_error_write(ev->srv, __FILE__, __LINE__, "S(D, S)",
63 "(set) write failed: ", fd, strerror(errno));
65 return -1;
68 return fd;
71 static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
72 struct dvpoll dopoll;
73 int ret;
75 dopoll.dp_timeout = timeout_ms;
76 dopoll.dp_nfds = ev->maxfds - 1;
77 dopoll.dp_fds = ev->devpollfds;
79 ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
81 return ret;
84 static int fdevent_solaris_devpoll_event_get_revent(fdevents *ev, size_t ndx) {
85 int r, poll_r;
87 r = 0;
88 poll_r = ev->devpollfds[ndx].revents;
90 /* map POLL* to FDEVEN_*; they are probably the same, but still. */
92 if (poll_r & POLLIN) r |= FDEVENT_IN;
93 if (poll_r & POLLOUT) r |= FDEVENT_OUT;
94 if (poll_r & POLLERR) r |= FDEVENT_ERR;
95 if (poll_r & POLLHUP) r |= FDEVENT_HUP;
96 if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
97 if (poll_r & POLLPRI) r |= FDEVENT_PRI;
99 return r;
102 static int fdevent_solaris_devpoll_event_get_fd(fdevents *ev, size_t ndx) {
103 return ev->devpollfds[ndx].fd;
106 static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
107 size_t i;
109 UNUSED(ev);
111 i = (last_ndx < 0) ? 0 : last_ndx + 1;
113 return i;
116 int fdevent_solaris_devpoll_reset(fdevents *ev) {
117 /* a forked process does only inherit the filedescriptor,
118 * but every operation on the device will lead to a EACCES */
119 if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
120 log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
121 "opening /dev/poll failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
123 return -1;
126 fd_close_on_exec(ev->devpoll_fd);
127 return 0;
129 int fdevent_solaris_devpoll_init(fdevents *ev) {
130 ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
131 #define SET(x) \
132 ev->x = fdevent_solaris_devpoll_##x;
134 SET(free);
135 SET(poll);
136 SET(reset);
138 SET(event_del);
139 SET(event_set);
141 SET(event_next_fdndx);
142 SET(event_get_fd);
143 SET(event_get_revent);
145 ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
146 force_assert(NULL != ev->devpollfds);
148 if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
149 log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
150 "opening /dev/poll failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
152 return -1;
155 /* we just wanted to check if it works */
156 close(ev->devpoll_fd);
158 ev->devpoll_fd = -1;
160 return 0;
163 #else
164 int fdevent_solaris_devpoll_init(fdevents *ev) {
165 UNUSED(ev);
167 log_error_write(ev->srv, __FILE__, __LINE__, "S",
168 "solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"");
170 return -1;
172 #endif