diff options
author | Luis Ontanon <luis.ontanon@gmail.com> | 2013-07-23 18:26:38 +0000 |
---|---|---|
committer | Luis Ontanon <luis.ontanon@gmail.com> | 2013-07-23 18:26:38 +0000 |
commit | c9e6eda76992311af7b33b8a6e1f21024c1cf251 (patch) | |
tree | f71fbdf44531f3c042432118f640bd74c24226a0 /echld | |
parent | ac16425a1f08909fa9a21347cc674e192ab22781 (diff) | |
download | wireshark-c9e6eda76992311af7b33b8a6e1f21024c1cf251.tar.gz wireshark-c9e6eda76992311af7b33b8a6e1f21024c1cf251.tar.bz2 wireshark-c9e6eda76992311af7b33b8a6e1f21024c1cf251.zip |
Yet another iteration...
svn path=/trunk/; revision=50846
Diffstat (limited to 'echld')
-rw-r--r-- | echld/Makefile.common | 1 | ||||
-rw-r--r-- | echld/child.c | 1 | ||||
-rw-r--r-- | echld/common.c | 3 | ||||
-rw-r--r-- | echld/dispatcher.c | 27 | ||||
-rw-r--r-- | echld/echld.h | 25 | ||||
-rw-r--r-- | echld/parent.c | 131 |
6 files changed, 156 insertions, 32 deletions
diff --git a/echld/Makefile.common b/echld/Makefile.common index a8949a7a08..bc4b709142 100644 --- a/echld/Makefile.common +++ b/echld/Makefile.common @@ -48,6 +48,7 @@ LIBECHLD_MORE_SRC = \ ../capture-pcap-util-unix.c \ ../capture_stop_conditions.c \ ../capture_sync.c \ + ../cfile.c \ ../cfutils.c \ ../clopts_common.c \ ../conditions.c \ diff --git a/echld/child.c b/echld/child.c index 3d83e6425b..15817fe504 100644 --- a/echld/child.c +++ b/echld/child.c @@ -359,7 +359,6 @@ static param_t child_params[] = { {NULL,NULL,NULL,NULL} }; - static char* param_get_params(char** err _U_) { return paramset_get_params_list(child_params,PARAM_LIST_FMT); } diff --git a/echld/common.c b/echld/common.c index afa7185688..cf454a0352 100644 --- a/echld/common.c +++ b/echld/common.c @@ -429,6 +429,9 @@ char* paramset_get_params_list(param_t* paramsets,const char* fmt) { return s; } + + + /* encoders and decoders */ diff --git a/echld/dispatcher.c b/echld/dispatcher.c index 714858d2fa..e7ab35bdc6 100644 --- a/echld/dispatcher.c +++ b/echld/dispatcher.c @@ -358,7 +358,7 @@ static char* param_get_loop_timeout(char** err _U_) { static echld_bool_t param_set_loop_timeout(char* val , char** err ) { char* p; - int usec = (int)strtol(val, &p, 10); /*XXX: "10ms" or "500us" or "1s" */ + int usec = (int)strtol(val, &p, 10); /* now usecs 2DO: "10ms" or "500us" or "1s" */ if (p<=val) { *err = g_strdup("not an integer"); @@ -469,14 +469,15 @@ static void dispatcher_clear_child(struct dispatcher_child* c) { } static void set_dumpcap_pid(int pid) { + dispatcher->dumpcap_pid = pid; } static void preinit_epan(char* argv0, int (*main)(int, char **)) { - char *gpf_path, *pf_path; + // char *gpf_path, *pf_path; char *gdp_path, *dp_path; - int gpf_open_errno, gpf_read_errno; - int pf_open_errno, pf_read_errno; + // int gpf_open_errno, gpf_read_errno; + // int pf_open_errno, pf_read_errno; int gdp_open_errno, gdp_read_errno; int dp_open_errno, dp_read_errno; char* error; @@ -518,20 +519,27 @@ static void preinit_epan(char* argv0, int (*main)(int, char **)) { /* disabled protocols as per configuration file */ set_disabled_protos_list(); - initialize_funnel_ops(); setlocale(LC_ALL, ""); - - stuff.prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path, &pf_open_errno, &pf_read_errno, &pf_path); - // check 4 errors + DISP_DBG((1,"---5")); read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno); - // check 4 errors + + DISP_DBG((1,"---6")); cap_file_init(&stuff.cfile); + DISP_DBG((1,"---7")); + DISP_DBG((1,"---8")); timestamp_set_precision(TS_PREC_AUTO_USEC); + // sleep(10); + + // initialize_funnel_ops(); + // stuff.prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path, &pf_open_errno, &pf_read_errno, &pf_path); + // check 4 errors + + DISP_DBG((2,"epan preinit done")); } @@ -1060,6 +1068,7 @@ void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, in preinit_epan(argv0,main); + DISP_WRITE(dispatcher->parent_out, NULL, 0, ECHLD_HELLO, 0); exit(dispatcher_loop()); } diff --git a/echld/echld.h b/echld/echld.h index a30c2d3f0e..9176ee46fa 100644 --- a/echld/echld.h +++ b/echld/echld.h @@ -83,17 +83,28 @@ typedef struct timeval tv_t; typedef void (*cleanup_cb_t)(void*); typedef int (*main_t)(int, char**); /* a pointer to main() */ +/* these are called after a new child is created. + * chld_id = -1 on error/timeout + */ +typedef void (*echld_new_cb_t)(void* child_data, const char* err); + /* I will be passed to echld_initialize() */ typedef struct _echld_init { echld_encoding_t encoding; /* only JSON for now */ + char* argv0; /* the value of argv[0] */ main_t main; - cleanup_cb_t after_fork_cb; /* to be called after fork to free the - child processes from entities of the parent */ + + echld_new_cb_t dispatcher_hello_cb; /* child_data will be a pointer to this echld_init_t */ + + cleanup_cb_t after_fork_cb; /* to be called by dispatcher just after fork to free + the child processes from entities of the parent */ void* after_fork_cb_data; cleanup_cb_t at_term_cb; /* to be called after echld_terminate() is done */ void* at_term_cb_data; + + void* user_data; /* free for you to use */ } echld_init_t; /* will initialize echld forking the dispatcher and registering protocols and taps */ @@ -169,15 +180,21 @@ WS_DLL_PUBLIC char* echld_decode(echld_msg_type_t, enc_msg_t*); WS_DLL_PUBLIC enc_msg_t* echld_new_child_params(void); -/* takes the em, and param=value pairs of strings, NULL to end. + + +/* takes the em, and param=value pairs of strings, NULL to end. echld_new_child_params_add_params(em,param1_str,val1_str,param2_str,val2_str,NULL); */ WS_DLL_PUBLIC void echld_new_child_params_add_params(enc_msg_t*, ...); WS_DLL_PUBLIC enc_msg_t* echld_new_child_params_merge(enc_msg_t*, enc_msg_t*); +#define ECHLD_NC_PARAMS_FMT " %s='%s',\n" /* param='value' */ +/* truncate takes off last N chars from the last item's fmt or prefix on empty */ +WS_DLL_PUBLIC char* echld_new_child_params_str(enc_msg_t* em, const char* prefix, const char* postfix, int truncate, const char* fmt); + /* create a new worker process */ -WS_DLL_PUBLIC echld_chld_id_t echld_new(enc_msg_t* new_child_parameters, void* child_data); +WS_DLL_PUBLIC echld_chld_id_t echld_new(enc_msg_t* new_child_parameters, echld_new_cb_t cb, void* child_data); /* will return NULL on error, if NULL is also ok for you use echld_get_error() */ WS_DLL_PUBLIC void* echld_get_data(echld_chld_id_t); diff --git a/echld/parent.c b/echld/parent.c index 635b2c4419..811535d932 100644 --- a/echld/parent.c +++ b/echld/parent.c @@ -1,6 +1,6 @@ -/* echld_dispatcher.c +/* parent.c * epan working child API internals - * Parent process routines and definitions () + * Parent process routines and definitions * * $Id$ * @@ -52,6 +52,7 @@ typedef struct _hdlr { typedef struct _echld_child { int chld_id; void* data; + echld_new_cb_t cb; child_state_t state; GArray* handlers; GArray* reqs; @@ -161,7 +162,7 @@ void parent_reaper(int sig) { int pid; int status; - if (sig != SIGCHLD) { + if (sig == SIGCHLD) { PARENT_FATAL((3333,"Must be SIGCHLD!")); } @@ -172,6 +173,7 @@ void parent_reaper(int sig) { if (! parent.closing) { /* crashed */ + sleep(120); PARENT_FATAL((DISPATCHER_DEAD,"Dispatcher process dead")); } @@ -184,6 +186,35 @@ void parent_reaper(int sig) { return; } +static echld_bool_t hello_cb(echld_msg_type_t type, enc_msg_t* msg_buff, void* ud) { + echld_init_t* init = (echld_init_t*)ud; + char* err = NULL; + int errnum = 0; + + if (init && init->dispatcher_hello_cb) { + switch(type) { + case ECHLD_ERROR: + parent.dec->error(msg_buff, &errnum ,&err); + break; + case ECHLD_TIMEOUT: + err = g_strdup("timedout"); + break; + default: + err = g_strdup_printf("Wrong MSG 'HELLO' expected, got '%s",TY(type)); + break; + case ECHLD_HELLO: + break; + } + + init->dispatcher_hello_cb(ud,err); + if (err) g_free(err); + } + + return TRUE; +} + + + /* will initialize epan registering protocols and taps */ void echld_initialize(echld_init_t* init) { int from_disp[2]; @@ -258,6 +289,8 @@ void echld_initialize(echld_init_t* init) { signal(SIGCHLD,parent_reaper); //close(to_disp[0]); //close(from_disp[1]); + if (init->dispatcher_hello_cb) echld_msgh(0, ECHLD_HELLO, hello_cb, init); + PARENT_DBG((3,"Ready")); } } @@ -450,19 +483,33 @@ static echld_bool_t parent_dead_child(echld_msg_type_t type, enc_msg_t* ba, void return 0; } -static echld_bool_t parent_get_hello(echld_msg_type_t type, enc_msg_t* ba _U_, void* data) { +static echld_bool_t parent_get_hello(echld_msg_type_t type, enc_msg_t* ba, void* data) { echld_t* c = (echld_t*)data; + int err_id; + char* err = NULL; switch (type) { case ECHLD_HELLO: PARENT_DBG((1,"Child[%d]: =>IDLE",c->chld_id)); c->state = IDLE; - return TRUE; + break; case ECHLD_ERROR: - case ECHLD_TIMED_OUT: + parent.dec->error(ba,&err_id,&err); + break; + case ECHLD_TIMEOUT: + err = g_strdup("timedout"); + break; default: - return FALSE; + err = g_strdup_printf("Wrong MSG 'HELLO' expected, got '%s",TY(type)); + break; } + + if (c->cb) + c->cb(c->data,err); + + if (err) g_free(err); + + return TRUE; } @@ -477,7 +524,7 @@ static int msgh_attach(echld_t* c, echld_msg_type_t t, echld_msg_cb_t resp_cb, v static int next_chld_id = 1; -extern int echld_new(enc_msg_t* new_child_em, void* child_data) { +extern int echld_new(enc_msg_t* new_child_em, echld_new_cb_t cb, void* child_data) { echld_t* c = get_child(-1); if (!c) return -1; @@ -485,6 +532,7 @@ extern int echld_new(enc_msg_t* new_child_em, void* child_data) { c->chld_id = (next_chld_id++); c->data = child_data; c->state = CREATING; + c->cb = cb; PARENT_DBG((1,"Child[%d]: =>CREATING",c->chld_id)); @@ -714,13 +762,17 @@ static reqh_t* get_req(echld_t* c, int reqh_id) { static hdlr_t* get_next_hdlr_for_type(echld_t* c, echld_msg_type_t t, int* cookie) { int imax = c->handlers->len; + hdlr_t* r = NULL; - for (;*cookie<imax;(*cookie)++) { - if (((hdlr_t*)(c->handlers->data))[*cookie].type == t) - return &( ((hdlr_t*)(c->handlers->data))[*cookie] ) ; + for (;(*cookie)<imax;(*cookie)++) { + if (((hdlr_t*)(c->handlers->data))[*cookie].type == t) { + r = &( ((hdlr_t*)(c->handlers->data))[*cookie] ); + (*cookie)++; + break; + } } - return NULL; + return r; } static long parent_read_frame(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t t, echld_reqh_id_t reqh_id, void* data _U_) { @@ -732,7 +784,7 @@ static long parent_read_frame(guint8* b, size_t len, echld_chld_id_t chld_id, ec if (c) { reqh_t* r = get_req(c, reqh_id); - int i = 0; + int i; hdlr_t* h; gboolean go_ahead = TRUE; @@ -747,14 +799,15 @@ static long parent_read_frame(guint8* b, size_t len, echld_chld_id_t chld_id, ec r->tv.tv_sec = 0; r->tv.tv_usec = 0; - PARENT_DBG((2,"hanlded by reqh_id=%d msg='%s'",reqh_id,go_ahead?"retrying":"done")); + PARENT_DBG((2,"handled by reqh_id=%d msg='%s'",reqh_id,go_ahead?"retrying":"done")); } + i=0; while(go_ahead && ( h = get_next_hdlr_for_type(c,t,&i))) { if (h->cb) go_ahead = h->cb(t,ba,h->cb_data); - PARENT_DBG((2,"hanlded by t='%c' msgh_id=%d msg='%s'",h->type, h->id,go_ahead?"retrying":"done")); + PARENT_DBG((2,"handled by t='%s' msgh_id=%d msg='%s'",TY(h->type), h->id,go_ahead?"retrying":"done")); } } else { PARENT_DBG((1,"parent_read_frame: No such child")); @@ -780,7 +833,7 @@ extern int echld_fd_read(fd_set* rfds, fd_set* efds) { } if (FD_ISSET(parent.reader.fd,rfds)) { - PARENT_DBG((1,"reading from dispatcher")); + PARENT_DBG((3,"reading from dispatcher")); echld_read_frame(&(parent.reader),parent_read_frame,&(parent)); } @@ -798,7 +851,7 @@ extern int echld_select(int nfds _U_, fd_set* rfds, fd_set* wfds, fd_set* efds, echld_fdset(rfds,efds); - PARENT_DBG((2,"Select()")); + PARENT_DBG((5,"Select()")); r_nfds = select(FD_SETSIZE, rfds, wfds, efds, timeout); echld_fd_read(rfds,efds); @@ -829,7 +882,47 @@ enc_msg_t* echld_new_child_params_merge(enc_msg_t* em1, enc_msg_t* em2) { return (enc_msg_t*)ba; } -WS_DLL_PUBLIC void echld_new_child_params_add_params(enc_msg_t* em, ...) { +char* echld_new_child_params_str(enc_msg_t* em, const char* prefix, const char* postfix, int trunc_n, const char* fmt) { + GByteArray* ba = (GByteArray*)em; + GString* str = g_string_new(prefix); + char* p = (char*) ba->data; + int tot_len = ba->len; + long rem = tot_len; + p[rem-1] = '\0'; /* make sure last char is null */ + + while(rem > 2) { + char* param = p; + long param_len = strlen(param)+1; + char* value = p + param_len; + long value_len; + + rem -= param_len; + + if (rem < 0) { + g_string_free(str,TRUE); + return NULL; + } + + value_len = strlen(value)+1; + + rem -= value_len; + p = value + value_len; + + if (rem < 0) { + g_string_free(str,TRUE); + return NULL; + } + + g_string_append_printf(str,fmt,param,value); + } + g_string_truncate(str, str->len - trunc_n); + g_string_append(str,postfix); + p = str->str; + g_string_free(str,FALSE); + return p; +} + +void echld_new_child_params_add_params(enc_msg_t* em, ...) { GByteArray* ba = (GByteArray*) em; va_list ap; @@ -850,3 +943,5 @@ WS_DLL_PUBLIC void echld_new_child_params_add_params(enc_msg_t* em, ...) { va_end(ap); } + + |