diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2010-07-12 18:03:39 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2010-07-12 18:03:39 +0000 |
commit | d70b966950f6d1e270311c555c5c22ed5847254b (patch) | |
tree | 86f938a0a2104887f551cb8a5ee40f766691dab0 /lib | |
parent | 1fbe451d284d3ee70462fa6aac6a3f83d0e8ea3e (diff) |
Update to 1.4.14b.
From their change log:
o Fix memory-leak of signal handler array with kqueue. [backport]
o Make evutil_make_socket_nonblocking() leave any other flags alone.
o Adjusted fcntl() retval comparison on evutil_make_socket_nonblocking().
o Re-add event_siglcb; some old code _was_ still using it. :(
o Fix a free(NULL) in min_heap.h
o Clean up properly when adding a signal handler fails.
Also a local change to use an int rather than a long for fcntl().
ok guenther deraadt
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libevent/buffer.c | 8 | ||||
-rw-r--r-- | lib/libevent/event.c | 30 | ||||
-rw-r--r-- | lib/libevent/evutil.c | 17 | ||||
-rw-r--r-- | lib/libevent/kqueue.c | 10 | ||||
-rw-r--r-- | lib/libevent/min_heap.h | 4 | ||||
-rw-r--r-- | lib/libevent/signal.c | 21 |
6 files changed, 67 insertions, 23 deletions
diff --git a/lib/libevent/buffer.c b/lib/libevent/buffer.c index 142d5b33a4f..8a3b9d1b850 100644 --- a/lib/libevent/buffer.c +++ b/lib/libevent/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.17 2010/04/21 20:02:40 nicm Exp $ */ +/* $OpenBSD: buffer.c,v 1.18 2010/07/12 18:03:38 nicm Exp $ */ /* * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu> @@ -260,6 +260,9 @@ evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out, char *line; unsigned int i, n_to_copy, n_to_drain; + if (n_read_out) + *n_read_out = 0; + /* depending on eol_style, set start_of_eol to the first character * in the newline, and end_of_eol to one after the last character. */ switch (eol_style) { @@ -318,8 +321,7 @@ evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out, n_to_drain = end_of_eol - data; if ((line = malloc(n_to_copy+1)) == NULL) { - fprintf(stderr, "%s: out of memory\n", __func__); - evbuffer_drain(buffer, n_to_drain); + event_warn("%s: out of memory\n", __func__); return (NULL); } diff --git a/lib/libevent/event.c b/lib/libevent/event.c index c02da41af94..5bca0683815 100644 --- a/lib/libevent/event.c +++ b/lib/libevent/event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: event.c,v 1.23 2010/04/21 21:02:46 nicm Exp $ */ +/* $OpenBSD: event.c,v 1.24 2010/07/12 18:03:38 nicm Exp $ */ /* * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> @@ -111,6 +111,10 @@ struct event_base *current_base = NULL; extern struct event_base *evsignal_base; static int use_monotonic; +/* Handle signals - This is a deprecated interface */ +int (*event_sigcb)(void); /* Signal callback when gotsig is set */ +volatile sig_atomic_t event_gotsig; /* Set in signal handler */ + /* Prototypes */ static void event_queue_insert(struct event_base *, struct event *, int); static void event_queue_remove(struct event_base *, struct event *, int); @@ -177,6 +181,9 @@ event_base_new(void) if ((base = calloc(1, sizeof(struct event_base))) == NULL) event_err(1, "%s: calloc", __func__); + event_sigcb = NULL; + event_gotsig = 0; + detect_monotonic(); gettime(base, &base->event_tv); @@ -319,7 +326,10 @@ event_base_priority_init(struct event_base *base, int npriorities) if (base->event_count_active) return (-1); - if (base->nactivequeues && npriorities != base->nactivequeues) { + if (npriorities == base->nactivequeues) + return (0); + + if (base->nactivequeues) { for (i = 0; i < base->nactivequeues; ++i) { free(base->activequeues[i]); } @@ -385,7 +395,7 @@ event_process_active(struct event_base *base) ncalls--; ev->ev_ncalls = ncalls; (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg); - if (base->event_break) + if (event_gotsig || base->event_break) return; } } @@ -490,6 +500,18 @@ event_base_loop(struct event_base *base, int flags) break; } + /* You cannot use this interface for multi-threaded apps */ + while (event_gotsig) { + event_gotsig = 0; + if (event_sigcb) { + res = (*event_sigcb)(); + if (res == -1) { + errno = EINTR; + return (-1); + } + } + } + timeout_correct(base, &tv); tv_p = &tv; @@ -993,7 +1015,7 @@ event_queue_insert(struct event_base *base, struct event *ev, int queue) const char * event_get_version(void) { - return ("1.4.13-stable"); + return ("1.4.14b-stable"); } /* diff --git a/lib/libevent/evutil.c b/lib/libevent/evutil.c index 940467ab8e4..c33d5b6ac45 100644 --- a/lib/libevent/evutil.c +++ b/lib/libevent/evutil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: evutil.c,v 1.2 2010/04/21 21:02:47 nicm Exp $ */ +/* $OpenBSD: evutil.c,v 1.3 2010/07/12 18:03:38 nicm Exp $ */ /* * Copyright (c) 2007 Niels Provos <provos@citi.umich.edu> @@ -170,10 +170,17 @@ evutil_make_socket_nonblocking(int fd) ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking); } #else - if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { - event_warn("fcntl(O_NONBLOCK)"); - return -1; -} + { + 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; + } + } #endif return 0; } diff --git a/lib/libevent/kqueue.c b/lib/libevent/kqueue.c index 33aa46d1c29..3fc162ad778 100644 --- a/lib/libevent/kqueue.c +++ b/lib/libevent/kqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kqueue.c,v 1.25 2010/04/21 20:02:40 nicm Exp $ */ +/* $OpenBSD: kqueue.c,v 1.26 2010/07/12 18:03:38 nicm Exp $ */ /* * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> @@ -63,6 +63,7 @@ #include "event.h" #include "event-internal.h" #include "log.h" +#include "evsignal.h" #define EVLIST_X_KQINKERNEL 0x1000 @@ -287,8 +288,8 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv) } else { ev = (struct event *)events[i].udata; - if (!(ev->ev_events & EV_PERSIST)) - ev->ev_flags &= ~EVLIST_X_KQINKERNEL; + if (!(ev->ev_events & EV_PERSIST)) + ev->ev_flags &= ~EVLIST_X_KQINKERNEL; event_active(ev, which, 1); } @@ -439,12 +440,15 @@ kq_dealloc(struct event_base *base, void *arg) { struct kqop *kqop = arg; + evsignal_dealloc(base); + if (kqop->changes) free(kqop->changes); if (kqop->events) free(kqop->events); if (kqop->kq >= 0 && kqop->pid == getpid()) close(kqop->kq); + memset(kqop, 0, sizeof(struct kqop)); free(kqop); } diff --git a/lib/libevent/min_heap.h b/lib/libevent/min_heap.h index d1023545fa1..8bf35f982df 100644 --- a/lib/libevent/min_heap.h +++ b/lib/libevent/min_heap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: min_heap.h,v 1.1 2010/04/21 20:02:40 nicm Exp $ */ +/* $OpenBSD: min_heap.h,v 1.2 2010/07/12 18:03:38 nicm Exp $ */ /* * Copyright (c) 2006 Maxim Yegorushkin <maxim.yegorushkin@gmail.com> @@ -58,7 +58,7 @@ int min_heap_elem_greater(struct event *a, struct event *b) } void min_heap_ctor(min_heap_t* s) { s->p = 0; s->n = 0; s->a = 0; } -void min_heap_dtor(min_heap_t* s) { free(s->p); } +void min_heap_dtor(min_heap_t* s) { if(s->p) free(s->p); } void min_heap_elem_init(struct event* e) { e->min_heap_idx = -1; } int min_heap_empty(min_heap_t* s) { return 0u == s->n; } unsigned min_heap_size(min_heap_t* s) { return s->n; } diff --git a/lib/libevent/signal.c b/lib/libevent/signal.c index c5ce41596dd..81f3ed461e5 100644 --- a/lib/libevent/signal.c +++ b/lib/libevent/signal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.c,v 1.14 2010/04/21 20:02:40 nicm Exp $ */ +/* $OpenBSD: signal.c,v 1.15 2010/07/12 18:03:38 nicm Exp $ */ /* * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> @@ -186,12 +186,14 @@ _evsignal_set_handler(struct event_base *base, if (sigaction(evsignal, &sa, sig->sh_old[evsignal]) == -1) { event_warn("sigaction"); free(sig->sh_old[evsignal]); + sig->sh_old[evsignal] = NULL; return (-1); } #else if ((sh = signal(evsignal, handler)) == SIG_ERR) { event_warn("signal"); free(sig->sh_old[evsignal]); + sig->sh_old[evsignal] = NULL; return (-1); } *sig->sh_old[evsignal] = sh; @@ -346,12 +348,19 @@ evsignal_dealloc(struct event_base *base) _evsignal_restore_handler(base, i); } - EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]); - base->sig.ev_signal_pair[0] = -1; - EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]); - base->sig.ev_signal_pair[1] = -1; + if (base->sig.ev_signal_pair[0] != -1) { + EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]); + base->sig.ev_signal_pair[0] = -1; + } + if (base->sig.ev_signal_pair[1] != -1) { + EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]); + base->sig.ev_signal_pair[1] = -1; + } base->sig.sh_old_max = 0; /* per index frees are handled in evsignal_del() */ - free(base->sig.sh_old); + if (base->sig.sh_old) { + free(base->sig.sh_old); + base->sig.sh_old = NULL; + } } |