Yet another iteration...
authorlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 23 Jul 2013 18:26:38 +0000 (18:26 +0000)
committerlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 23 Jul 2013 18:26:38 +0000 (18:26 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@50846 f5534014-38df-0310-8fa8-9805f1628bb7

echld/Makefile.common
echld/child.c
echld/common.c
echld/dispatcher.c
echld/echld.h
echld/parent.c

index a8949a7a08d106b7f2f2ababaf973b51d20e8f3c..bc4b709142e99fb1267fa39b8e1e0e1cd2354229 100644 (file)
@@ -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 \
index 3d83e6425bcab808d8a1b554a0cec15e01000769..15817fe5041e84a98c01de502f1a09975e2f424e 100644 (file)
@@ -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);
 }
index afa71856887de703f19cee7bf4f773ef8ab2e409..cf454a0352cc61b084dcf1d8e8162928561fec3e 100644 (file)
@@ -429,6 +429,9 @@ char* paramset_get_params_list(param_t* paramsets,const char* fmt) {
        return s;
 }
 
+
+
+
 /* encoders and decoders */
 
 
index 714858d2faf9d593a3f4f4185be88dd9f1923c67..e7ab35bdc6901e54b411557109c0a909b8c40f86 100644 (file)
@@ -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());
 }
 
index a30c2d3f0e682ef4c5c7d7c920a50832bf42b0ea..9176ee46fa42a6c4728024f9c1621bd56b97e99a 100644 (file)
@@ -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);
index 635b2c4419bf03e53584e289863e57d3a41b405e..811535d9326c909a1a426e2e1ecf7f84b48af1e1 100644 (file)
@@ -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);
 
 }
+
+