Update to 1.4.14b.
authornicm <nicm@openbsd.org>
Mon, 12 Jul 2010 18:03:38 +0000 (18:03 +0000)
committernicm <nicm@openbsd.org>
Mon, 12 Jul 2010 18:03:38 +0000 (18:03 +0000)
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

lib/libevent/buffer.c
lib/libevent/event.c
lib/libevent/evutil.c
lib/libevent/kqueue.c
lib/libevent/min_heap.h
lib/libevent/signal.c

index 142d5b3..8a3b9d1 100644 (file)
@@ -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);
        }
 
index c02da41..5bca068 100644 (file)
@@ -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");
 }
 
 /* 
index 940467a..c33d5b6 100644 (file)
@@ -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;
 }
index 33aa46d..3fc162a 100644 (file)
@@ -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);
 }
index d102354..8bf35f9 100644 (file)
@@ -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; }
index c5ce415..81f3ed4 100644 (file)
@@ -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;
+       }
 }