diff options
author | Luis Ontanon <luis.ontanon@gmail.com> | 2013-07-01 01:49:34 +0000 |
---|---|---|
committer | Luis Ontanon <luis.ontanon@gmail.com> | 2013-07-01 01:49:34 +0000 |
commit | baee2e21f7020c77f41001bd759f8d41063eba3f (patch) | |
tree | d192ec49151c48a6862b1694b0aefba14fb8b158 /echld/dispatcher.c | |
parent | e03edbf713c9af37b452e1c3f1917f1e2c69ca72 (diff) |
ANother iteration,
- started harvesting pieces from tshark.
- fixed? signal handlers
- interactive test program
very hard to debug... set follow-on-fork doesn't seem to work on my mac. Need linux I guess...
svn path=/trunk/; revision=50273
Diffstat (limited to 'echld/dispatcher.c')
-rw-r--r-- | echld/dispatcher.c | 91 |
1 files changed, 73 insertions, 18 deletions
diff --git a/echld/dispatcher.c b/echld/dispatcher.c index e300c06c1d..910f54255c 100644 --- a/echld/dispatcher.c +++ b/echld/dispatcher.c @@ -36,6 +36,7 @@ struct dispatcher_child { echld_reader_t reader; int write_fd; int pid; + int reqh_id; gboolean closing; }; @@ -290,10 +291,10 @@ static char* param_get_interfaces(char** err) { return s; } -static struct timeval disp_loop_timeout; +static long disp_loop_timeout_usec = DISPATCHER_WAIT_INITIAL; static char* param_get_loop_to(char** err _U_) { - return g_strdup_printf("%d.%06ds",(int)disp_loop_timeout.tv_sec, (int)disp_loop_timeout.tv_usec ); + return g_strdup_printf("%fs", (((float)disp_loop_timeout_usec)/1000000.0) ); } static echld_bool_t param_set_loop_to(char* val , char** err ) { @@ -305,17 +306,39 @@ static echld_bool_t param_set_loop_to(char* val , char** err ) { return FALSE; } - disp_loop_timeout.tv_sec = usec / 1000000; - disp_loop_timeout.tv_usec = usec % 1000000; + disp_loop_timeout_usec = usec; return TRUE; } +GString *comp_info_str; +GString *runtime_info_str; + +static char* param_get_version(char** err _U_) { + char* str; + + str = g_strdup_printf("Echld " VERSION "%s\n" + "\n" + "%s" + "\n" + "%s" + "\n" + "%s", + wireshark_svnversion, get_copyright_info(), comp_info_str->str, + runtime_info_str->str); + + g_string_free(runtime_info_str,TRUE); + g_string_free(comp_info_str,TRUE); + + return str; +} + static param_t disp_params[] = { #ifdef DEBUG_DISPATCHER {"dbg_level", param_get_dbg_level, param_set_dbg_level}, # endif + {"version",param_get_version,NULL}, {"loop_timeout",param_get_loop_to,param_set_loop_to}, {"interfaces",param_get_interfaces,NULL}, {NULL,NULL,NULL} }; @@ -351,6 +374,7 @@ static void dispatcher_clear_child(struct dispatcher_child* c) { c->reader.fd = -1; c->write_fd = -1; c->pid = -1; + c->reqh_id = -1; c->closing = FALSE; } @@ -361,13 +385,34 @@ static void set_dumpcap_pid(int pid) { static void preinit_epan(char* argv0, int (*main)(int, char **)) { char* init_progfile_dir_error = init_progfile_dir(argv0, main); + comp_info_str = g_string_new("Compiled "); + get_compiled_version_info(comp_info_str, NULL, epan_get_compiled_version_info); + + runtime_info_str = g_string_new("Running "); + get_runtime_version_info(runtime_info_str, NULL); + if (init_progfile_dir_error) { DISP_FATAL((CANNOT_PREINIT_EPAN,"Failed epan_preinit: msg='%s'",init_progfile_dir_error)); } + /* Add it to the information to be reported on a crash. */ + ws_add_crash_info("Echld " VERSION "%s\n%s\n%s", + wireshark_svnversion, comp_info_str->str, runtime_info_str->str); + capture_sync_set_fetch_dumpcap_pid_cb(set_dumpcap_pid); +#ifdef _WIN32 + arg_list_utf_16to8(argc, argv); + create_app_running_mutex(); +#if !GLIB_CHECK_VERSION(2,31,0) + g_thread_init(NULL); +#endif +#endif /* _WIN32 */ + + + init_process_policies(); + /* Here we do initialization of parts of epan that will be the same for every child we fork */ DISP_DBG((2,"epan preinit")); @@ -392,7 +437,6 @@ void dispatcher_reaper(int sig) { struct dispatcher_child* cc = dispatcher->children; int max_children = dispatcher->max_children; int pid = waitpid(-1, &status, WNOHANG); - GByteArray* em; int reqh_id_save = dispatcher->reqh_id; dispatcher->reqh_id = 0; @@ -409,9 +453,10 @@ void dispatcher_reaper(int sig) { struct dispatcher_child* c = &(cc[i]); if ( c->pid == pid ) { if (c->closing || dispatcher->closing) { - em = dispatcher->enc.to_parent->child_dead("OK"); + DISP_WRITE(dispatcher->parent_out, NULL, c->chld_id, ECHLD_CLOSING, c->reqh_id); } else { char* s = NULL; + GByteArray* em; if (WIFEXITED(status)) { s = g_strdup_printf( @@ -433,12 +478,12 @@ void dispatcher_reaper(int sig) { em = dispatcher->enc.to_parent->child_dead(s); dispatcher_err(ECHLD_ERR_CRASHED_CHILD, s); if (s) g_free(s); + DISP_WRITE(dispatcher->parent_out, em, c->chld_id, ECHLD_CHILD_DEAD, 0); + if (em) g_byte_array_free(em,TRUE); } CHLD_SET_STATE(c,CLOSED); - DISP_WRITE(dispatcher->parent_out, em, c->chld_id, ECHLD_CHILD_DEAD, 0); dispatcher_clear_child(c); - g_byte_array_free(em,TRUE); dispatcher->reqh_id = reqh_id_save; return; } @@ -474,8 +519,9 @@ static long dispatch_to_parent(guint8* b, size_t len, echld_chld_id_t chld_id, e GByteArray in_ba; struct dispatcher_child* c = (struct dispatcher_child*)data; - dispatcher->reqh_id = reqh_id; + dispatcher->reqh_id = c->reqh_id = reqh_id; + in_ba.data = b; in_ba.len = (guint)len; @@ -487,7 +533,10 @@ static long dispatch_to_parent(guint8* b, size_t len, echld_chld_id_t chld_id, e case ECHLD_ERROR: break; case ECHLD_TIMED_OUT: break; case ECHLD_HELLO: CHLD_SET_STATE(c,IDLE); break; - case ECHLD_CLOSING: CHLD_SET_STATE(c,CLOSED); break; + case ECHLD_CLOSING: + c->closing = TRUE; + CHLD_SET_STATE(c,CLOSING); + break; case ECHLD_PARAM: break; case ECHLD_PONG: break; case ECHLD_FILE_OPENED: CHLD_SET_STATE(c,READING); break; @@ -771,12 +820,10 @@ static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ec - int dispatcher_loop(void) { int parent_out = dispatcher->parent_out; int parent_in = dispatcher->parent_in.fd; struct dispatcher_child* children = dispatcher->children; - volatile int pforce = 0; DISP_DBG((5,"LOOP in_fd=%d out_fd=%d",parent_in, parent_out)); @@ -786,7 +833,7 @@ int dispatcher_loop(void) { struct dispatcher_child* c; int nfds; int nchld = 0; - + struct timeval disp_loop_timeout; FD_ZERO(&rfds); FD_ZERO(&efds); @@ -803,16 +850,21 @@ int dispatcher_loop(void) { } } - DISP_DBG((5,"Select()ing nchld=%d usecs=%d",nchld,disp_loop_timeout.tv_usec)); + DISP_DBG((4,"Select()ing nchld=%d",nchld,disp_loop_timeout.tv_usec)); + + disp_loop_timeout.tv_sec = (int)(disp_loop_timeout_usec / 1000000); + disp_loop_timeout.tv_usec = (int)(disp_loop_timeout_usec % 1000000); nfds = select(FD_SETSIZE, &rfds, NULL, &efds, &disp_loop_timeout); + DISP_DBG((5,"Select()ed nfds=%d",nchld,nfds)); + if (nfds < 0) { DISP_DBG((1,"select error='%s'",strerror(errno) )); continue; } - if ( pforce || FD_ISSET(parent_in, &rfds)) { + if ( FD_ISSET(parent_in, &rfds)) { long st = echld_read_frame(&(dispatcher->parent_in), dispatch_to_child, dispatcher); if (st < 0) { @@ -865,6 +917,9 @@ int dispatcher_loop(void) { return 1; } +void dispatcher_alrm(int sig _U_) { + DISP_DBG((1,"ALRM received")); +} void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, int (*main)(int, char **)) { static struct dispatcher d; @@ -873,9 +928,6 @@ void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, in int dbg_fd; #endif - disp_loop_timeout.tv_sec = 0; - disp_loop_timeout.tv_usec = DISPATCHER_WAIT_INITIAL; - DISP_DBG_INIT(); #ifdef DEBUG_DISPATCHER dbg_fd = fileno(debug_fp); @@ -889,6 +941,9 @@ void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, in signal(SIGPIPE,dispatcher_sig); signal(SIGINT,SIG_IGN); signal(SIGCONT,SIG_IGN); + signal(SIGABRT,dispatcher_sig); + signal(SIGHUP,dispatcher_sig); + signal(SIGALRM,dispatcher_alrm); dispatcher = &d; |