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