X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=blobdiff_plain;f=mon%2Fmons.c;h=b0a04003bed9ac71b0b8316d6200d52e15805547;hp=4d638d6842da98ca0c0a1c8dda0feaee3859f183;hb=7458d6a285fa526fd8cec03e1bbb497650a0e405;hpb=733b18697117cbc63ab3d9e44510c9850916ec90 diff --git a/mon/mons.c b/mon/mons.c index 4d638d6..b0a0400 100644 --- a/mon/mons.c +++ b/mon/mons.c @@ -46,12 +46,17 @@ #include "mons_handlers.h" +static void mons_sweep_procs(MONS_INSTANCE *mons); + static int mons_destructor(void *object) { MONS_INSTANCE *mons = talloc_get_type_abort(object, MONS_INSTANCE); - if (mons->handlers) { + if (mons->handlers) g_ptr_array_unref(mons->handlers); - } + + if (mons->pids) + g_array_unref(mons->pids); + return 0; } @@ -88,6 +93,12 @@ MONS_INSTANCE *mons_new(TALLOC_CTX *mem_ctx) talloc_free(mons); return NULL; } + + mons->pids = g_array_new(FALSE, FALSE, sizeof(pid_t)); + if (mons->pids == NULL) { + talloc_free(mons); + return NULL; + } } return mons; } @@ -214,8 +225,8 @@ int mons_accept(MONS_INSTANCE *mons, int listen) int conn=-1; int pid=-1; - if (0 > (conn = accept(listen, NULL, NULL))) { - perror("Error from monitoring interface accept()"); + if (0 > (conn = tr_sock_accept(listen))) { + tr_err("mons_accept: Error accepting connection"); return 1; } @@ -226,19 +237,60 @@ int mons_accept(MONS_INSTANCE *mons, int listen) if (pid == 0) { close(listen); - tr_gss_handle_connection(conn, - "trustmonitor", mons->hostname, /* acceptor name */ - mons->auth_handler, mons->cookie, /* auth callback and cookie */ - mons_req_cb, mons /* req callback and cookie */ - ); + switch(tr_gss_handle_connection(conn, + "trustmonitor", mons->hostname, /* acceptor name */ + mons->auth_handler, mons->cookie, /* auth callback and cookie */ + mons_req_cb, mons /* req callback and cookie */ + )) { + case TR_GSS_SUCCESS: + /* do nothing */ + break; + + case TR_GSS_ERROR: + tr_debug("mons_accept: Error returned by tr_gss_handle_connection()"); + break; + + default: + tr_err("mons_accept: Unexpected value returned by tr_gss_handle_connection()"); + break; + } close(conn); exit(0); /* exit to kill forked child process */ - } else { - close(conn); } + /* Only the parent process gets here */ + close(conn); + g_array_append_val(mons->pids, pid); + /* clean up any processes that have completed */ - while (waitpid(-1, 0, WNOHANG) > 0); + mons_sweep_procs(mons); return 0; } + +void mons_sweep_procs(MONS_INSTANCE *mons) +{ + guint ii; + pid_t pid; + int status; + + /* loop backwards over the array so we can remove elements as we go */ + for (ii=mons->pids->len; ii > 0; ii--) { + /* ii-1 is the current index */ + pid = g_array_index(mons->pids, pid_t, ii-1); + if (waitpid(pid, &status, WNOHANG) > 0) { + /* the process exited */ + tr_debug("mons_sweep_procs: monitoring process %d terminated.", pid); + + g_array_remove_index_fast(mons->pids, ii-1); /* disturbs only indices >= ii-1 which we've already handled */ + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) + tr_debug("mons_sweep_procs: monitoring process %d succeeded.", pid); + else + tr_debug("mons_sweep_procs: monitoring process %d exited with status %d.", pid, WTERMSIG(status)); + } else if (WIFSIGNALED(status)) { + tr_debug("mons_sweep_procs: monitoring process %d terminated by signal %d.", pid, WTERMSIG(status)); + } + } + } +}