tevent: rename signal handler functions to start with tevent_common_
[tprouty/samba.git] / lib / tevent / tevent_signal.c
index 36907af6beda8d88c0da2f434180eff442cb6f57..c21ba209af2e70fdcb61f19f11e11b914ac170bb 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <signal.h>
 #include "replace.h"
 #include "system/filesys.h"
-#include "system/select.h"
+#include "system/wait.h"
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
@@ -41,12 +40,16 @@ struct sigcounter {
 #define SIG_SEEN(s, n) (s).seen += (n)
 #define SIG_PENDING(s) ((s).seen != (s).count)
 
+struct tevent_common_signal_list {
+       struct tevent_common_signal_list *prev, *next;
+       struct tevent_signal *se;
+};
 
 /*
   the poor design of signals means that this table must be static global
 */
 static struct sig_state {
-       struct signal_event *sig_handlers[NUM_SIGNALS+1];
+       struct tevent_common_signal_list *sig_handlers[NUM_SIGNALS+1];
        struct sigaction *oldact[NUM_SIGNALS+1];
        struct sigcounter signal_count[NUM_SIGNALS+1];
        struct sigcounter got_signal;
@@ -72,7 +75,7 @@ static uint32_t sig_count(struct sigcounter s)
 /*
   signal handler - redirects to registered signals
 */
-static void signal_handler(int signum)
+static void tevent_common_signal_handler(int signum)
 {
        char c = 0;
        SIG_INCREMENT(sig_state->signal_count[signum]);
@@ -85,12 +88,13 @@ static void signal_handler(int signum)
 /*
   signal handler with SA_SIGINFO - redirects to registered signals
 */
-static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
+static void tevent_common_signal_handler_info(int signum, siginfo_t *info,
+                                             void *uctx)
 {
        uint32_t count = sig_count(sig_state->signal_count[signum]);
        sig_state->sig_info[signum][count] = *info;
 
-       signal_handler(signum);
+       tevent_common_signal_handler(signum);
 
        /* handle SA_SIGINFO */
        if (count+1 == SA_INFO_QUEUE_COUNT) {
@@ -105,13 +109,27 @@ static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
 }
 #endif
 
+static int tevent_common_signal_list_destructor(struct tevent_common_signal_list *sl)
+{
+       DLIST_REMOVE(sig_state->sig_handlers[sl->se->signum], sl);
+       return 0;
+}
+
 /*
   destroy a signal event
 */
-static int signal_event_destructor(struct signal_event *se)
+static int tevent_signal_destructor(struct tevent_signal *se)
 {
-       se->event_ctx->num_signal_handlers--;
-       DLIST_REMOVE(sig_state->sig_handlers[se->signum], se);
+       struct tevent_common_signal_list *sl;
+       sl = talloc_get_type(se->additional_data,
+                            struct tevent_common_signal_list);
+
+       if (se->event_ctx) {
+               DLIST_REMOVE(se->event_ctx->signal_events, se);
+       }
+
+       talloc_free(sl);
+
        if (sig_state->sig_handlers[se->signum] == NULL) {
                /* restore old handler, if any */
                sigaction(se->signum, sig_state->oldact[se->signum], NULL);
@@ -123,13 +141,14 @@ static int signal_event_destructor(struct signal_event *se)
                }
 #endif
        }
+
        return 0;
 }
 
 /*
   this is part of the pipe hack needed to avoid the signal race condition
 */
-static void signal_pipe_handler(struct event_context *ev, struct fd_event *fde, 
+static void signal_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, 
                                uint16_t flags, void *private)
 {
        char c[16];
@@ -141,16 +160,20 @@ static void signal_pipe_handler(struct event_context *ev, struct fd_event *fde,
   add a signal event
   return NULL on failure (memory allocation error)
 */
-struct signal_event *common_event_add_signal(struct event_context *ev, 
-                                            TALLOC_CTX *mem_ctx,
-                                            int signum,
-                                            int sa_flags,
-                                            event_signal_handler_t handler, 
-                                            void *private_data) 
+struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
+                                              TALLOC_CTX *mem_ctx,
+                                              int signum,
+                                              int sa_flags,
+                                              tevent_signal_handler_t handler,
+                                              void *private_data,
+                                              const char *handler_name,
+                                              const char *location)
 {
-       struct signal_event *se;
+       struct tevent_signal *se;
+       struct tevent_common_signal_list *sl;
 
        if (signum >= NUM_SIGNALS) {
+               errno = EINVAL;
                return NULL;
        }
 
@@ -163,17 +186,29 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
                }
        }
 
-       se = talloc(mem_ctx?mem_ctx:ev, struct signal_event);
+       se = talloc(mem_ctx?mem_ctx:ev, struct tevent_signal);
        if (se == NULL) return NULL;
 
        se->event_ctx           = ev;
-       se->handler             = handler;
-       se->private_data        = private_data;
        se->signum              = signum;
        se->sa_flags            = sa_flags;
-       
+       se->handler             = handler;
+       se->private_data        = private_data;
+       se->handler_name        = handler_name;
+       se->location            = location;
+       se->additional_data     = NULL;
+
+       sl = talloc(se, struct tevent_common_signal_list);
+       if (!sl) {
+               talloc_free(se);
+               return NULL;
+       }
+       sl->se = se;
+       se->additional_data     = sl;
+
        /* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */
        if (!talloc_reference(se, sig_state)) {
+               talloc_free(se);
                return NULL;
        }
 
@@ -181,12 +216,12 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
        if (sig_state->sig_handlers[signum] == NULL) {
                struct sigaction act;
                ZERO_STRUCT(act);
-               act.sa_handler   = signal_handler;
+               act.sa_handler = tevent_common_signal_handler;
                act.sa_flags = sa_flags;
 #ifdef SA_SIGINFO
                if (sa_flags & SA_SIGINFO) {
                        act.sa_handler   = NULL;
-                       act.sa_sigaction = signal_handler_info;
+                       act.sa_sigaction = tevent_common_signal_handler_info;
                        if (sig_state->sig_info[signum] == NULL) {
                                sig_state->sig_info[signum] = talloc_array(sig_state, siginfo_t, SA_INFO_QUEUE_COUNT);
                                if (sig_state->sig_info[signum] == NULL) {
@@ -207,9 +242,11 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
                }
        }
 
-       DLIST_ADD(sig_state->sig_handlers[signum], se);
+       DLIST_ADD(se->event_ctx->signal_events, se);
+       DLIST_ADD(sig_state->sig_handlers[signum], sl);
 
-       talloc_set_destructor(se, signal_event_destructor);
+       talloc_set_destructor(se, tevent_signal_destructor);
+       talloc_set_destructor(sl, tevent_common_signal_list_destructor);
 
        /* we need to setup the pipe hack handler if not already
           setup */
@@ -220,10 +257,13 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
                        ev_set_blocking(sig_state->pipe_hack[0], false);
                        ev_set_blocking(sig_state->pipe_hack[1], false);
                }
-               ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0],
-                                           EVENT_FD_READ, signal_pipe_handler, NULL);
+               ev->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0],
+                                            TEVENT_FD_READ, signal_pipe_handler, NULL);
+               if (!ev->pipe_fde) {
+                       talloc_free(se);
+                       return NULL;
+               }
        }
-       ev->num_signal_handlers++;
 
        return se;
 }
@@ -233,7 +273,7 @@ struct signal_event *common_event_add_signal(struct event_context *ev,
   check if a signal is pending
   return != 0 if a signal was pending
 */
-int common_event_check_signal(struct event_context *ev)
+int tevent_common_check_signal(struct tevent_context *ev)
 {
        int i;
 
@@ -242,15 +282,16 @@ int common_event_check_signal(struct event_context *ev)
        }
        
        for (i=0;i<NUM_SIGNALS+1;i++) {
-               struct signal_event *se, *next;
+               struct tevent_common_signal_list *sl, *next;
                struct sigcounter counter = sig_state->signal_count[i];
                uint32_t count = sig_count(counter);
 
                if (count == 0) {
                        continue;
                }
-               for (se=sig_state->sig_handlers[i];se;se=next) {
-                       next = se->next;
+               for (sl=sig_state->sig_handlers[i];sl;sl=next) {
+                       struct tevent_signal *se = sl->se;
+                       next = sl->next;
 #ifdef SA_SIGINFO
                        if (se->sa_flags & SA_SIGINFO) {
                                int j;