void * kq_init(void) { int kq; struct kqop *kqueueop; /* Disable kqueue when this environment variable is set */ if (getenv("EVENT_NOKQUEUE")) return (NULL); if (!(kqueueop = calloc(1, sizeof(struct kqop)))) return (NULL); /* Initalize the kernel queue */ if ((kq = kqueue()) == -1) { event_warn("kqueue"); free (kqueueop); return (NULL); } kqueueop->kq = kq; /* Initalize fields */ kqueueop->changes = malloc(NEVENT * sizeof(struct kevent)); if (kqueueop->changes == NULL) { free (kqueueop); return (NULL); } kqueueop->events = malloc(NEVENT * sizeof(struct kevent)); if (kqueueop->events == NULL) { free (kqueueop->changes); free (kqueueop); return (NULL); } kqueueop->nevents = NEVENT; /* Check for Mac OS X kqueue bug. */ kqueueop->changes[0].ident = -1; kqueueop->changes[0].filter = EVFILT_READ; kqueueop->changes[0].flags = EV_ADD; /* * If kqueue works, then kevent will succeed, and it will * stick an error in events[0]. If kqueue is broken, then * kevent will fail. */ if (kevent(kq, kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 || kqueueop->events[0].ident != -1 || kqueueop->events[0].flags != EV_ERROR) { event_warn("%s: detected broken kqueue; not using.", __func__); free(kqueueop->changes); free(kqueueop->events); free(kqueueop); close(kq); return (NULL); } return (kqueueop); }
int _evsignal_restore_handler(struct event_base *base, int evsignal) { int ret = 0; struct evsignal_info *sig = &base->sig; #ifdef HAVE_SIGACTION struct sigaction *sh; #else ev_sighandler_t *sh; #endif /* restore previous handler */ sh = sig->sh_old[evsignal]; sig->sh_old[evsignal] = NULL; #ifdef HAVE_SIGACTION if (sigaction(evsignal, sh, NULL) == -1) { event_warn("sigaction"); ret = -1; } #else if (signal(evsignal, *sh) == SIG_ERR) { event_warn("signal"); ret = -1; } #endif free(sh); return ret; }
static void * kq_init(struct event_base *base) { int kq = -1; struct kqop *kqueueop = NULL; if (!(kqueueop = mm_calloc(1, sizeof(struct kqop)))) return (NULL); /* Initialize the kernel queue */ if ((kq = kqueue()) == -1) { event_warn("kqueue"); goto err; } kqueueop->kq = kq; kqueueop->pid = getpid(); /* Initialize fields */ kqueueop->changes = mm_calloc(NEVENT, sizeof(struct kevent)); if (kqueueop->changes == NULL) goto err; kqueueop->events = mm_calloc(NEVENT, sizeof(struct kevent)); if (kqueueop->events == NULL) goto err; kqueueop->events_size = kqueueop->changes_size = NEVENT; /* Check for Mac OS X kqueue bug. */ memset(&kqueueop->changes[0], 0, sizeof kqueueop->changes[0]); kqueueop->changes[0].ident = -1; kqueueop->changes[0].filter = EVFILT_READ; kqueueop->changes[0].flags = EV_ADD; /* * If kqueue works, then kevent will succeed, and it will * stick an error in events[0]. If kqueue is broken, then * kevent will fail. */ if (kevent(kq, kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 || kqueueop->events[0].ident != -1 || kqueueop->events[0].flags != EV_ERROR) { event_warn("%s: detected broken kqueue; not using.", __func__); goto err; } base->evsigsel = &kqsigops; base->evsigbase = kqueueop; return (kqueueop); err: if (kqueueop) kqop_free(kqueueop); return (NULL); }
/* Helper: set the signal handler for evsignal to handler in base, so that * we can restore the original handler when we clear the current one. */ int _evsignal_set_handler(struct event_base *base, int evsignal, void (*handler)(int)) { struct sigaction sa; struct evsignal_info *sig = &base->sig; void *p; /* * resize saved signal handler array up to the highest signal number. * a dynamic array is used to keep footprint on the low side. */ if (evsignal >= sig->sh_old_max) { int new_max = evsignal + 1; event_debug(("%s: evsignal (%d) >= sh_old_max (%d), resizing", __func__, evsignal, sig->sh_old_max)); p = reallocarray(sig->sh_old, new_max, sizeof(*sig->sh_old)); if (p == NULL) { event_warn("realloc"); return (-1); } memset((char *)p + sig->sh_old_max * sizeof(*sig->sh_old), 0, (new_max - sig->sh_old_max) * sizeof(*sig->sh_old)); sig->sh_old_max = new_max; sig->sh_old = p; } /* allocate space for previous handler out of dynamic array */ sig->sh_old[evsignal] = malloc(sizeof *sig->sh_old[evsignal]); if (sig->sh_old[evsignal] == NULL) { event_warn("malloc"); return (-1); } /* save previous handler and setup new handler */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler; sa.sa_flags |= SA_RESTART; sigfillset(&sa.sa_mask); if (sigaction(evsignal, &sa, sig->sh_old[evsignal]) == -1) { event_warn("sigaction"); free(sig->sh_old[evsignal]); sig->sh_old[evsignal] = NULL; return (-1); } return (0); }
static int http_connect(const char *address, u_short port) { /* Stupid code for connecting */ #ifdef WIN32 struct hostent *he; struct sockaddr_in sin; #else struct addrinfo ai, *aitop; char strport[NI_MAXSERV]; #endif struct sockaddr *sa; int slen; int fd; #ifdef WIN32 if (!(he = gethostbyname(address))) { event_warn("gethostbyname"); } memcpy(&sin.sin_addr, he->h_addr_list[0], he->h_length); sin.sin_family = AF_INET; sin.sin_port = htons(port); slen = sizeof(struct sockaddr_in); sa = (struct sockaddr*)&sin; #else memset(&ai, 0, sizeof (ai)); ai.ai_family = AF_INET; ai.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof (strport), "%d", port); if (getaddrinfo(address, strport, &ai, &aitop) != 0) { event_warn("getaddrinfo"); return (-1); } sa = aitop->ai_addr; slen = aitop->ai_addrlen; #endif fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) event_err(1, "socket failed"); if (connect(fd, sa, slen) == -1) event_err(1, "connect failed"); #ifndef WIN32 freeaddrinfo(aitop); #endif return (fd); }
int evutil_make_socket_nonblocking(int fd) { int flags; if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) { event_warn("fcntl(%d, F_GETFL)", fd); return -1; } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { event_warn("fcntl(%d, F_SETFL)", fd); return -1; } return 0; }
int msg_run_assign(struct msg *msg, int off, const struct run* value) { if (!msg->run_set || off < 0 || off >= msg->run_length) return (-1); { int had_error = 0; struct evbuffer *tmp = NULL; run_clear(msg->run_data[off]); if ((tmp = evbuffer_new()) == NULL) { event_warn("%s: evbuffer_new()", __func__); had_error = 1; goto done; } run_marshal(tmp, value); if (run_unmarshal(msg->run_data[off], tmp) == -1) { event_warnx("%s: run_unmarshal", __func__); had_error = 1; goto done; } done:if (tmp != NULL) evbuffer_free(tmp); if (had_error) { run_clear(msg->run_data[off]); return (-1); } } return (0); }
static int epoll_recalc(struct event_base *base, void *arg, int max) { struct epollop *epollop = arg; if (max >= epollop->nfds) { struct evepoll *fds; int nfds; nfds = epollop->nfds; while (nfds <= max) nfds <<= 1; fds = realloc(epollop->fds, nfds * sizeof(struct evepoll)); if (fds == NULL) { event_warn("realloc"); return (-1); } epollop->fds = fds; memset(fds + epollop->nfds, 0, (nfds - epollop->nfds) * sizeof(struct evepoll)); epollop->nfds = nfds; } return (0); }
static int select_resize(struct selectop *sop, int fdsz) { fd_set *readset_in = NULL; fd_set *writeset_in = NULL; if (sop->event_readset_in) check_selectop(sop); if ((readset_in = mm_realloc(sop->event_readset_in, fdsz)) == NULL) goto error; sop->event_readset_in = readset_in; if ((writeset_in = mm_realloc(sop->event_writeset_in, fdsz)) == NULL) goto error; sop->event_writeset_in = writeset_in; sop->resize_out_sets = 1; memset((char *)sop->event_readset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); memset((char *)sop->event_writeset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); sop->event_fdsz = fdsz; check_selectop(sop); return (0); error: event_warn("malloc"); return (-1); }
struct msg * msg_new_with_arg(void *unused) { struct msg *tmp; if ((tmp = malloc(sizeof(struct msg))) == NULL) { event_warn("%s: malloc", __func__); return (NULL); } tmp->base = &__msg_base; tmp->from_name_data = NULL; tmp->from_name_set = 0; tmp->to_name_data = NULL; tmp->to_name_set = 0; tmp->attack_data = NULL; tmp->attack_set = 0; tmp->run_data = NULL; tmp->run_length = 0; tmp->run_num_allocated = 0; tmp->run_set = 0; return (tmp); }
struct run * run_new_with_arg(void *unused) { struct run *tmp; if ((tmp = malloc(sizeof(struct run))) == NULL) { event_warn("%s: malloc", __func__); return (NULL); } tmp->base = &__run_base; tmp->how_data = NULL; tmp->how_set = 0; tmp->some_bytes_data = NULL; tmp->some_bytes_length = 0; tmp->some_bytes_set = 0; memset(tmp->fixed_bytes_data, 0, sizeof(tmp->fixed_bytes_data)); tmp->fixed_bytes_set = 0; tmp->notes_data = NULL; tmp->notes_length = 0; tmp->notes_num_allocated = 0; tmp->notes_set = 0; tmp->large_number_data = 0; tmp->large_number_set = 0; tmp->other_numbers_data = NULL; tmp->other_numbers_length = 0; tmp->other_numbers_num_allocated = 0; tmp->other_numbers_set = 0; return (tmp); }
static int devpoll_recalc(struct event_base *base, void *arg, int max) { struct devpollop *devpollop = arg; if (max > devpollop->nfds) { struct evdevpoll *fds; int nfds; nfds = devpollop->nfds; while (nfds < max) nfds <<= 1; fds = realloc(devpollop->fds, nfds * sizeof(struct evdevpoll)); if (fds == NULL) { event_warn("realloc"); return (-1); } devpollop->fds = fds; memset(fds + devpollop->nfds, 0, (nfds - devpollop->nfds) * sizeof(struct evdevpoll)); devpollop->nfds = nfds; } return (0); }
static void evsig_handler(int sig) { int save_errno = errno; #ifdef WIN32 int socket_errno = EVUTIL_SOCKET_ERROR(); #endif if (evsig_base == NULL) { event_warn( "%s: received signal %d, but have no base configured", __func__, sig); return; } evsig_base->sig.evsigcaught[sig]++; evsig_base->sig.evsig_caught = 1; #ifndef _EVENT_HAVE_SIGACTION signal(sig, evsig_handler); #endif /* Wake up our notification mechanism */ send(evsig_base->sig.ev_signal_pair[0], "a", 1, 0); errno = save_errno; #ifdef WIN32 EVUTIL_SET_SOCKET_ERROR(socket_errno); #endif }
int event_kq_notify_base_(struct event_base *base) { struct kqop *kqop = base->evbase; #if defined(EVFILT_USER) && defined(NOTE_TRIGGER) struct kevent kev; struct timespec timeout = { 0, 0 }; #endif if (! kqop->notify_event_added) return -1; #if defined(EVFILT_USER) && defined(NOTE_TRIGGER) memset(&kev, 0, sizeof(kev)); kev.ident = NOTIFY_IDENT; kev.filter = EVFILT_USER; kev.fflags = NOTE_TRIGGER; if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1) { event_warn("kevent: triggering EVFILT_USER event"); return -1; } return 0; #else return -1; #endif }
static int kq_dispatch(struct event_base *base, void *arg, struct timeval *tv) { struct kqop *kqop = arg; struct kevent *changes = kqop->changes; struct kevent *events = kqop->events; struct event *ev; struct timespec ts, *ts_p = NULL; int i, res; if (tv != NULL) { TIMEVAL_TO_TIMESPEC(tv, &ts); ts_p = &ts; } res = kevent(kqop->kq, changes, kqop->nchanges, events, kqop->nevents, ts_p); kqop->nchanges = 0; if (res == -1) { if (errno != EINTR) { event_warn("kevent"); return (-1); } return (0); } event_debug(("%s: kevent reports %d", __func__, res)); for (i = 0; i < res; i++) { int which = 0; if (events[i].flags & EV_ERROR) { if (events[i].data == EBADF || events[i].data == EINVAL || events[i].data == ENOENT) continue; errno = events[i].data; return (-1); } if (events[i].filter == EVFILT_READ) { which |= EV_READ; } else if (events[i].filter == EVFILT_WRITE) { which |= EV_WRITE; } else if (events[i].filter == EVFILT_SIGNAL) { which |= EV_SIGNAL; } if (!which) continue; if (events[i].filter == EVFILT_SIGNAL) { struct event_list *head = (struct event_list *)events[i].udata; TAILQ_FOREACH(ev, head, ev_signal_next) { event_active(ev, which, events[i].data); } } else {
static int select_dispatch(struct event_base *base, void *arg, struct timeval *tv) { int res, i, j; struct selectop *sop = arg; check_selectop(sop); memcpy(sop->event_readset_out, sop->event_readset_in, sop->event_fdsz); memcpy(sop->event_writeset_out, sop->event_writeset_in, sop->event_fdsz); res = select(sop->event_fds + 1, sop->event_readset_out, sop->event_writeset_out, NULL, tv); check_selectop(sop); if (res == -1) { if (errno != EINTR) { event_warn("select"); return (-1); } evsignal_process(base); return (0); } else if (base->sig.evsignal_caught) { evsignal_process(base); } event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); i = arc4random_uniform(sop->event_fds + 1); for (j = 0; j <= sop->event_fds; ++j) { struct event *r_ev = NULL, *w_ev = NULL; if (++i >= sop->event_fds+1) i = 0; res = 0; if (FD_ISSET(i, sop->event_readset_out)) { r_ev = sop->event_r_by_fd[i]; res |= EV_READ; } if (FD_ISSET(i, sop->event_writeset_out)) { w_ev = sop->event_w_by_fd[i]; res |= EV_WRITE; } if (r_ev && (res & r_ev->ev_events)) { event_active(r_ev, res & r_ev->ev_events, 1); } if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) { event_active(w_ev, res & w_ev->ev_events, 1); } } check_selectop(sop); return (0); }
static int devpoll_dispatch(struct event_base *base, struct timeval *tv) { struct devpollop *devpollop = base->evbase; struct pollfd *events = devpollop->events; struct dvpoll dvp; int i, res, timeout = -1; if (devpollop->nchanges) devpoll_commit(devpollop); if (tv != NULL) timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000; dvp.dp_fds = devpollop->events; dvp.dp_nfds = devpollop->nevents; dvp.dp_timeout = timeout; EVBASE_RELEASE_LOCK(base, th_base_lock); res = ioctl(devpollop->dpfd, DP_POLL, &dvp); EVBASE_ACQUIRE_LOCK(base, th_base_lock); if (res == -1) { if (errno != EINTR) { event_warn("ioctl: DP_POLL"); return (-1); } return (0); } event_debug(("%s: devpoll_wait reports %d", __func__, res)); for (i = 0; i < res; i++) { int which = 0; int what = events[i].revents; if (what & POLLHUP) what |= POLLIN | POLLOUT; else if (what & POLLERR) what |= POLLIN | POLLOUT; if (what & POLLIN) which |= EV_READ; if (what & POLLOUT) which |= EV_WRITE; if (!which) continue; /* XXX(niels): not sure if this works for devpoll */ evmap_io_active_(base, events[i].fd, which); } return (0); }
static void * devpoll_init(struct event_base *base) { int dpfd, nfiles = NEVENT; struct rlimit rl; struct devpollop *devpollop; /* Disable devpoll when this environment variable is set */ if (getenv("EVENT_NODEVPOLL")) return (NULL); if (!(devpollop = calloc(1, sizeof(struct devpollop)))) return (NULL); if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) nfiles = rl.rlim_cur - 1; /* Initialize the kernel queue */ if ((dpfd = open("/dev/poll", O_RDWR)) == -1) { event_warn("open: /dev/poll"); free(devpollop); return (NULL); } devpollop->dpfd = dpfd; /* Initialize fields */ devpollop->events = calloc(nfiles, sizeof(struct pollfd)); if (devpollop->events == NULL) { free(devpollop); close(dpfd); return (NULL); } devpollop->nevents = nfiles; devpollop->fds = calloc(nfiles, sizeof(struct evdevpoll)); if (devpollop->fds == NULL) { free(devpollop->events); free(devpollop); close(dpfd); return (NULL); } devpollop->nfds = nfiles; devpollop->changes = calloc(nfiles, sizeof(struct pollfd)); if (devpollop->changes == NULL) { free(devpollop->fds); free(devpollop->events); free(devpollop); close(dpfd); return (NULL); } evsignal_init(base); return (devpollop); }
int select_dispatch(struct event_base *base, void *arg, struct timeval *tv) { int res, i; struct selectop *sop = arg; check_selectop(sop); memcpy(sop->event_readset_out, sop->event_readset_in, sop->event_fdsz); memcpy(sop->event_writeset_out, sop->event_writeset_in, sop->event_fdsz); res = select(sop->event_fds + 1, sop->event_readset_out, sop->event_writeset_out, NULL, tv); check_selectop(sop); if (res == -1) { if (errno != EINTR) { event_warn("select"); return (-1); } evsignal_process(); return (0); } else if (evsignal_caught) evsignal_process(); event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); for (i = 0; i <= sop->event_fds; ++i) { struct event *r_ev = NULL, *w_ev = NULL; res = 0; if (FD_ISSET(i, sop->event_readset_out)) { r_ev = sop->event_r_by_fd[i]; res |= EV_READ; } if (FD_ISSET(i, sop->event_writeset_out)) { w_ev = sop->event_w_by_fd[i]; res |= EV_WRITE; } if (r_ev && (res & r_ev->ev_events)) { if (!(r_ev->ev_events & EV_PERSIST)) event_del(r_ev); event_active(r_ev, res & r_ev->ev_events, 1); } if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) { if (!(w_ev->ev_events & EV_PERSIST)) event_del(w_ev); event_active(w_ev, res & w_ev->ev_events, 1); } } check_selectop(sop); return (0); }
static int select_resize(struct selectop *sop, size_t fdsz) { size_t n_events, n_events_old; fd_set *readset_in = NULL; fd_set *writeset_in = NULL; fd_set *readset_out = NULL; fd_set *writeset_out = NULL; struct event **r_by_fd = NULL; struct event **w_by_fd = NULL; n_events = (fdsz/sizeof(fd_mask)) * NFDBITS; n_events_old = (sop->event_fdsz/sizeof(fd_mask)) * NFDBITS; if (sop->event_readset_in) check_selectop(sop); if ((readset_in = realloc(sop->event_readset_in, fdsz)) == NULL) goto error; sop->event_readset_in = readset_in; if ((readset_out = realloc(sop->event_readset_out, fdsz)) == NULL) goto error; sop->event_readset_out = readset_out; if ((writeset_in = realloc(sop->event_writeset_in, fdsz)) == NULL) goto error; sop->event_writeset_in = writeset_in; if ((writeset_out = realloc(sop->event_writeset_out, fdsz)) == NULL) goto error; sop->event_writeset_out = writeset_out; if ((r_by_fd = reallocarray(sop->event_r_by_fd, n_events, sizeof(struct event *))) == NULL) goto error; sop->event_r_by_fd = r_by_fd; if ((w_by_fd = reallocarray(sop->event_w_by_fd, n_events, sizeof(struct event *))) == NULL) goto error; sop->event_w_by_fd = w_by_fd; memset((char *)sop->event_readset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); memset((char *)sop->event_writeset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); memset(sop->event_r_by_fd + n_events_old, 0, (n_events-n_events_old) * sizeof(struct event*)); memset(sop->event_w_by_fd + n_events_old, 0, (n_events-n_events_old) * sizeof(struct event*)); sop->event_fdsz = fdsz; check_selectop(sop); return (0); error: event_warn("malloc"); return (-1); }
static int kq_insert(struct kqop *kqop, struct kevent *kev) { int nevents = kqop->nevents; if (kqop->nchanges == nevents) { struct kevent *newchange; struct kevent *newresult; nevents *= 2; newchange = realloc(kqop->changes, nevents * sizeof(struct kevent)); if (newchange == NULL) { event_warn("%s: malloc", __func__); return (-1); } kqop->changes = newchange; newresult = realloc(kqop->events, nevents * sizeof(struct kevent)); /* * If we fail, we don't have to worry about freeing, * the next realloc will pick it up. */ if (newresult == NULL) { event_warn("%s: malloc", __func__); return (-1); } kqop->events = newresult; kqop->nevents = nevents; } memcpy(&kqop->changes[kqop->nchanges++], kev, sizeof(struct kevent)); event_debug(("%s: fd %d %s%s", __func__, (int)kev->ident, kev->filter == EVFILT_READ ? "EVFILT_READ" : "EVFILT_WRITE", kev->flags == EV_DELETE ? " (del)" : "")); return (0); }
static int poll_add(struct event_base *base, int fd, short old, short events, void *_idx) { struct pollop *pop = base->evbase; struct pollfd *pfd = NULL; struct pollidx *idx = _idx; int i; EVUTIL_ASSERT((events & EV_SIGNAL) == 0); if (!(events & (EV_READ|EV_WRITE))) return (0); poll_check_ok(pop); if (pop->nfds + 1 >= pop->event_count) { struct pollfd *tmp_event_set; int tmp_event_count; if (pop->event_count < 32) tmp_event_count = 32; else tmp_event_count = pop->event_count * 2; /* We need more file descriptors */ tmp_event_set = mm_realloc(pop->event_set, tmp_event_count * sizeof(struct pollfd)); if (tmp_event_set == NULL) { event_warn("realloc"); return (-1); } pop->event_set = tmp_event_set; pop->event_count = tmp_event_count; pop->realloc_copy = 1; } i = idx->idxplus1 - 1; if (i >= 0) { pfd = &pop->event_set[i]; } else { i = pop->nfds++; pfd = &pop->event_set[i]; pfd->events = 0; pfd->fd = fd; idx->idxplus1 = i + 1; } pfd->revents = 0; if (events & EV_WRITE) pfd->events |= POLLOUT; if (events & EV_READ) pfd->events |= POLLIN; poll_check_ok(pop); return (0); }
static void * epoll_init(struct event_base *base) { int epfd, nfiles = NEVENT; struct rlimit rl; struct epollop *epollop; /* Disable epollueue when this environment variable is set */ if (getenv("EVENT_NOEPOLL")) return (NULL); if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) { /* * Solaris is somewhat retarded - it's important to drop * backwards compatibility when making changes. So, don't * dare to put rl.rlim_cur here. */ nfiles = rl.rlim_cur - 1; } /* Initalize the kernel queue */ if ((epfd = epoll_create(nfiles)) == -1) { if (errno != ENOSYS) event_warn("epoll_create"); return (NULL); } FD_CLOSEONEXEC(epfd); if (!(epollop = calloc(1, sizeof(struct epollop)))) return (NULL); epollop->epfd = epfd; /* Initalize fields */ epollop->events = malloc(nfiles * sizeof(struct epoll_event)); if (epollop->events == NULL) { free(epollop); return (NULL); } epollop->nevents = nfiles; epollop->fds = calloc(nfiles, sizeof(struct evepoll)); if (epollop->fds == NULL) { free(epollop->events); free(epollop); return (NULL); } epollop->nfds = nfiles; evsignal_init(base); return (epollop); }
/** * This function will be called by libevent when there is a connection * ready to be accepted. */ void on_accept(int fd, short ev, void *arg) { int client_fd; struct sockaddr_in client_addr; int client_len = sizeof(client_addr); struct client *client; static maxfd = 30000; client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len); if (client_fd == -1) { event_warn("accept failed, errno %d", WSAGetLastError()); return; } if( client_fd > maxfd + 1000 ) { maxfd = client_fd; printf( "maxfd %d\n", maxfd ); } setsockopt( client_fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&fd, sizeof(fd) ); /* Set the client socket to non-blocking mode. */ if (setnonblock(client_fd) < 0) event_warn("failed to set client socket non-blocking"); /* We¡¯ve accepted a new client, allocate a client object to * maintain the state of this client. */ client = (struct client*)calloc(1, sizeof(*client)); if (client == NULL) event_err(1, "malloc failed"); event_set(&client->ev_read, client_fd, EV_READ, on_read, client ); event_set(&client->ev_write, client_fd, EV_WRITE, on_write, client ); /* Setting up the event does not activate, add the event so it * becomes active. */ if( 0 != event_add(&client->ev_read, NULL) ) { close_client( client, client_fd ); } //printf("Accepted connection(%d) from %s\n", client_fd, inet_ntoa(client_addr.sin_addr)); }
char * evhttp_htmlescape(const char *html) { size_t i; size_t new_size = 0, old_size = 0; char *escaped_html, *p; if (html == NULL) return (NULL); old_size = strlen(html); for (i = 0; i < old_size; ++i) { const char *replaced = NULL; const size_t replace_size = html_replace(html[i], &replaced); if (replace_size > EV_SIZE_MAX - new_size) { event_warn("%s: html_replace overflow", __func__); return (NULL); } new_size += replace_size; } if (new_size == EV_SIZE_MAX) return (NULL); p = escaped_html = mm_malloc(new_size + 1); if (escaped_html == NULL) { event_warn("%s: malloc(%lu)", __func__, (unsigned long)(new_size + 1)); return (NULL); } for (i = 0; i < old_size; ++i) { const char *replaced = &html[i]; const size_t len = html_replace(html[i], &replaced); memcpy(p, replaced, len); p += len; } *p = '\0'; return (escaped_html); }
static int evport_del(struct event_base *base, int fd, short old, short events, void *p) { struct evport_data *evpd = base->evbase; struct fd_info *fdi; int i; int associated = 1; (void)p; check_evportop(evpd); if (evpd->ed_nevents < fd) { return (-1); } for (i = 0; i < EVENTS_PER_GETN; ++i) { if (evpd->ed_pending[i] == fd) { associated = 0; break; } } fdi = &evpd->ed_fds[fd]; if (events & EV_READ) fdi->fdi_what &= ~EV_READ; if (events & EV_WRITE) fdi->fdi_what &= ~EV_WRITE; if (associated) { if (!FDI_HAS_EVENTS(fdi) && port_dissociate(evpd->ed_port, PORT_SOURCE_FD, fd) == -1) { /* * Ignore EBADFD error the fd could have been closed * before event_del() was called. */ if (errno != EBADFD) { event_warn("port_dissociate"); return (-1); } } else { if (FDI_HAS_EVENTS(fdi)) { return (reassociate(evpd, fdi, fd)); } } } else { if ((fdi->fdi_what & (EV_READ|EV_WRITE)) == 0) { evpd->ed_pending[i] = -1; } } return 0; }
int evutil_make_socket_nonblocking(int fd) { #ifdef WIN32 { unsigned long nonblocking = 1; ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking); } #else { long flags; if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) { event_warn("fcntl(%d, F_GETFL)", fd); return -1; } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { event_warn("fcntl(%d, F_SETFL)", fd); return -1; } } #endif return 0; }
void * epoll_init(void) { int epfd, nfiles = NEVENT; struct rlimit rl; struct epollop *epollop; /* Disable epollueue when this environment variable is set */ if (getenv("EVENT_NOEPOLL")) return (NULL); if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) nfiles = rl.rlim_cur; /* Initalize the kernel queue */ if ((epfd = epoll_create(nfiles)) == -1) { event_warn("epoll_create"); return (NULL); } FD_CLOSEONEXEC(epfd); if (!(epollop = calloc(1, sizeof(struct epollop)))) return (NULL); epollop->epfd = epfd; /* Initalize fields */ epollop->events = malloc(nfiles * sizeof(struct epoll_event)); if (epollop->events == NULL) { free(epollop); return (NULL); } epollop->nevents = nfiles; epollop->fds = calloc(nfiles, sizeof(struct evepoll)); if (epollop->fds == NULL) { free(epollop->events); free(epollop); return (NULL); } epollop->nfds = nfiles; evsignal_init(&epollop->evsigmask); return (epollop); }
int evsig_restore_handler_(struct event_base *base, int evsignal) { int ret = 0; struct evsig_info *sig = &base->sig; #ifdef EVENT__HAVE_SIGACTION struct sigaction *sh; #else ev_sighandler_t *sh; #endif if (evsignal >= sig->sh_old_max) { /* Can't actually restore. */ /* XXXX.*/ return 0; } /* restore previous handler */ sh = sig->sh_old[evsignal]; sig->sh_old[evsignal] = NULL; #ifdef EVENT__HAVE_SIGACTION if (sigaction(evsignal, sh, NULL) == -1) { event_warn("sigaction"); ret = -1; } #else if (signal(evsignal, *sh) == SIG_ERR) { event_warn("signal"); ret = -1; } #endif mm_free(sh); return ret; }
int msg_attack_assign(struct msg *msg, const struct kill* value) { struct evbuffer *tmp = NULL; if (msg->attack_set) { kill_clear(msg->attack_data); msg->attack_set = 0; } else { msg->attack_data = kill_new(); if (msg->attack_data == NULL) { event_warn("%s: kill_new()", __func__); goto error; } } if ((tmp = evbuffer_new()) == NULL) { event_warn("%s: evbuffer_new()", __func__); goto error; } kill_marshal(tmp, value); if (kill_unmarshal(msg->attack_data, tmp) == -1) { event_warnx("%s: kill_unmarshal", __func__); goto error; } msg->attack_set = 1; evbuffer_free(tmp); return (0); error: if (tmp != NULL) evbuffer_free(tmp); if (msg->attack_data != NULL) { kill_free(msg->attack_data); msg->attack_data = NULL; } return (-1); }