• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/lighttpd-1.4.39/src/
1#include "fdevent.h"
2#include "buffer.h"
3#include "log.h"
4
5#include <sys/types.h>
6
7#include <unistd.h>
8#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
11#include <errno.h>
12#include <signal.h>
13#include <fcntl.h>
14
15#ifdef USE_SOLARIS_DEVPOLL
16
17# include <sys/devpoll.h>
18
19static void fdevent_solaris_devpoll_free(fdevents *ev) {
20	free(ev->devpollfds);
21	close(ev->devpoll_fd);
22}
23
24/* return -1 is fine here */
25
26static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) {
27	struct pollfd pfd;
28
29	if (fde_ndx < 0) return -1;
30
31	pfd.fd = fd;
32	pfd.events = POLLREMOVE;
33	pfd.revents = 0;
34
35	if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
36		log_error_write(ev->srv, __FILE__, __LINE__, "S(D, S)",
37			"(del) write failed: ", fd, strerror(errno));
38
39		return -1;
40	}
41
42	return -1;
43}
44
45static int fdevent_solaris_devpoll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
46	struct pollfd pfd;
47	int add = 0;
48
49	int pevents = 0;
50	if (events & FDEVENT_IN)  pevents |= POLLIN;
51	if (events & FDEVENT_OUT) pevents |= POLLOUT;
52
53	if (fde_ndx == -1) add = 1;
54
55	pfd.fd = fd;
56	pfd.events = pevents;
57	pfd.revents = 0;
58
59	if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
60		log_error_write(ev->srv, __FILE__, __LINE__, "S(D, S)",
61			"(set) write failed: ", fd, strerror(errno));
62
63		return -1;
64	}
65
66	return fd;
67}
68
69static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
70	struct dvpoll dopoll;
71	int ret;
72
73	dopoll.dp_timeout = timeout_ms;
74	dopoll.dp_nfds = ev->maxfds - 1;
75	dopoll.dp_fds = ev->devpollfds;
76
77	ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
78
79	return ret;
80}
81
82static int fdevent_solaris_devpoll_event_get_revent(fdevents *ev, size_t ndx) {
83	int r, poll_r;
84
85	r = 0;
86	poll_r = ev->devpollfds[ndx].revents;
87
88	/* map POLL* to FDEVEN_*; they are probably the same, but still. */
89
90	if (poll_r & POLLIN) r |= FDEVENT_IN;
91	if (poll_r & POLLOUT) r |= FDEVENT_OUT;
92	if (poll_r & POLLERR) r |= FDEVENT_ERR;
93	if (poll_r & POLLHUP) r |= FDEVENT_HUP;
94	if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
95	if (poll_r & POLLPRI) r |= FDEVENT_PRI;
96
97	return r;
98}
99
100static int fdevent_solaris_devpoll_event_get_fd(fdevents *ev, size_t ndx) {
101	return ev->devpollfds[ndx].fd;
102}
103
104static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
105	size_t i;
106
107	UNUSED(ev);
108
109	i = (last_ndx < 0) ? 0 : last_ndx + 1;
110
111	return i;
112}
113
114int fdevent_solaris_devpoll_reset(fdevents *ev) {
115	/* a forked process does only inherit the filedescriptor,
116	 * but every operation on the device will lead to a EACCES */
117	if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
118		log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
119			"opening /dev/poll failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
120
121		return -1;
122	}
123
124	fd_close_on_exec(ev->devpoll_fd);
125	return 0;
126}
127int fdevent_solaris_devpoll_init(fdevents *ev) {
128	ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
129#define SET(x) \
130	ev->x = fdevent_solaris_devpoll_##x;
131
132	SET(free);
133	SET(poll);
134	SET(reset);
135
136	SET(event_del);
137	SET(event_set);
138
139	SET(event_next_fdndx);
140	SET(event_get_fd);
141	SET(event_get_revent);
142
143	ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
144
145	if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
146		log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
147			"opening /dev/poll failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
148
149		return -1;
150	}
151
152	/* we just wanted to check if it works */
153	close(ev->devpoll_fd);
154
155	ev->devpoll_fd = -1;
156
157	return 0;
158}
159
160#else
161int fdevent_solaris_devpoll_init(fdevents *ev) {
162	UNUSED(ev);
163
164	log_error_write(ev->srv, __FILE__, __LINE__, "S",
165		"solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"");
166
167	return -1;
168}
169#endif
170