Patch: Elm ME+ 2.5 PLalpha46 -> Elm ME+ 2.5 PLalpha47 [5/7] (5/7)
From
Kari Hurtta@21:1/5 to
All on Sat Feb 10 14:46:35 2018
[continued from previous message]
+ int err = errno;
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvFailedSocketPair,
+ "Failed to create socket pair: %s"),
+ strerror(err));
+ }
+
+ fail:
+ return ret;
+ }
+
+ #endif
+
+ S_(have_qm_f have_non_blocking_qm)
+ static int have_non_blocking_qm P_((void));
+ static int have_non_blocking_qm()
+ {
+ int ret = 0;
+ int pid0 = getpid();
+
+ if (process_list) {
+ size_t i;
+
+ for (i = 0; i < process_list_len && !ret; i++) {
+ if (process_list[i]) {
+ int XX = 0;
+ if (RESOLV_PROCESS_magic != process_list[i]->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"have_non_blocking_qm",
+ "Bad magic number (resolv_process)",0);
+
+ XX = resolv_process_ok(process_list[i]);
+
+ DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: #%lu",
+ (unsigned long)i));
+ if (XX) {
+ DPRINT(Debug,12,(&Debug, " -- OK"));
+ ret = 1;
+ }
+ DPRINT(Debug,12,(&Debug, "\n"));
+
+ if (XX && process_list[i]->message) {
+ union action_routine_data data;
+
+ if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"have_non_blocking_qm",
+ "Bad magic number (resolv_message_state)",0);
+
+ if (process_list[i]->message->broken_pipe) {
+ DPRINT(Debug,12,(&Debug, " : #%lu -- broken pipe (or EOF)\n",
+ (unsigned long)i));
+
+ /* Not handled here */
+ }
+
+ if (process_list[i]->message->write_prepared) {
+ DPRINT(Debug,12,(&Debug, " : #%lu -- write prepared (busy)\n",
+ (unsigned long)i));
+ }
+
+ if (process_list[i]->message->query_in_progress) {
+ DPRINT(Debug,12,(&Debug, " : #%lu -- query in progress (busy)\n",
+ (unsigned long)i));
+ }
+
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
+ data.resolv = process_list[i]->message;
+ /* This should be no-op */
+ change_action(process_list[i]->socket,-1,
+ resolv_read_message,
+ process_list[i]->message->write_prepared ?
+ resolv_write_message : no_action_routine,
+
+ no_action_routine,
+ resolv_free_state,resolv_inc_state_refcount,data);
+ #endif
+
+ } else if (process_list[i]->message) {
+
+ if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"have_non_blocking_qm",
+ "Bad magic number (resolv_message_state)",0);
+
+ if (process_list[i]->message->broken_pipe) {
+ DPRINT(Debug,12,(&Debug, " : #%lu -- broken pipe (or EOF)\n",
+ (unsigned long)i));
+ }
+
+ if (process_list[i]->message->write_prepared) {
+ DPRINT(Debug,12,(&Debug, " : #%lu -- write prepared (busy)\n",
+ (unsigned long)i));
+ }
+
+ if (process_list[i]->message->query_in_progress) {
+ DPRINT(Debug,12,(&Debug, " : #%lu -- query in progress (busy)\n",
+ (unsigned long)i));
+ }
+ }
+
+ } else {
+ DPRINT(Debug,15,(&Debug, "have_non_blocking_qm: #%lu -- unused entry\n",
+ (unsigned long)i));
+ }
+ }
+ }
+
+ if (ret) {
+ DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Available\n"));
+ }
+
+ if (!ret) {
+
+ if (qm_non_blocking == query_mode) {
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET) && defined(BACKGROUD_PROCESSES)
+
+ struct resolv_process * pr = give_resolv_process(pid0);
+ if (pr) {
+ int r = res_init();
+
+ if (0 == r) {
+
+
+ DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Started\n"));
+ ret = 1;
+
+ } else if (r < 0) {
+ int err = errno;
+
+ DPRINT(Debug,12,(&Debug,
+ "have_non_blocking_qm: res_init failed: errno = %d (%s)\n",
+ err,strerror(err)));
+
+ lib_error(CATGETS(elm_msg_cat,
+ ResolvSet,
+ ResolvResInitFailed,
+ "Failed to initialize with res_init: %s"),
+ strerror(err));
+ }
+
+ free_resolv_process(&pr);
+ } else {
+ DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Failed to add process for res_send()\n"));
+
+ }
+ #else
+ DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: Not supported\n"));
+ #endif
+ } else {
+ DPRINT(Debug,12,(&Debug, "have_non_blocking_qm: query-mode=%d",
+ query_mode));
+ if (query_mode >= 0 && query_mode < NUM_query_mode) {
+ DPRINT(Debug,12,(&Debug, " %s",
+ QUERY_MODE[query_mode]));
+ }
+ DPRINT(Debug,12,(&Debug, "\n"));
+ }
+ }
+
+ DPRINT(Debug,12,(&Debug, "have_non_blocking_qm=%d (pid %d)\n",ret,pid0)); +
+ return ret;
+ }
+
+ static int prepare_write_message P_((struct resolv_message_state *st, int socket,
+ struct resolv_query_hdr *result_hdr,
+ unsigned char * buffer, size_t buffer_len));
+ static int prepare_write_message(st,socket,result_hdr,buffer,buffer_len)
+ struct resolv_message_state *st;
+ int socket;
+ struct resolv_query_hdr *result_hdr;
+ unsigned char * buffer;
+ size_t buffer_len;
+ {
+ int ret = 0;
+ int pid = getpid();
+
+ if (RESOLV_MESSAGE_STATE_magic != st->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"prepare_write_message",
+ "Bad magic number (resolv_message_state)",0);
+
+ if (RESOLV_QUERY_HDR_magic != result_hdr->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "prepare_write_message",
+ "Bad magic number (resolv_query_hdr)",0);
+
+ if (result_hdr->buflen != buffer_len)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "prepare_write_message",
+ "Bad buf_len",0);
+
+ if (st->write_prepared && st->write_pos) {
+ SIGDPRINT(Debug,14,(&Debug,
+ "prepare_write_message: [pid %d] socket=%d on middle of write\n",
+ pid,socket));
+ ret = 0;
+ } else {
+ union action_routine_data data;
+
+ if (buffer_len > st->write_buffer_size) {
+ struct resolv_query_hdr Z = NULL_resolv_query_hdr;
+ struct resolv_sizeupdate U = NULL_resolv_sizeupdate;
+ union resolv_sizeupdate_p update_buffer;
+
+ unsigned short A = buffer_len;
+ if (A < RESOLV_BUFSIZE)
+ A = RESOLV_BUFSIZE;
+ if (A < sizeof U)
+ A = sizeof U;
+
+ SIGDPRINT(Debug,14,(&Debug,
+ "prepare_write_message: [pid %d] socket=%d: Changing write buffer size %lu => %d (need write %lu bytes)\n",
+ pid,socket,(unsigned long)(st->write_buffer_size),A,(unsigned long)buffer_len));
+
+ st->write_buffer_size = A;
+ st->write_buffer = safe_realloc(st->write_buffer,st->write_buffer_size);
+
+ U.querysize = st->write_buffer_size;
+ U.anssize = st->read_buffer_size;
+ update_buffer.update = &U;
+
+ Z.buflen = sizeof U;
+ Z.senderpid = pid;
+ Z.msg = qm_sizeupdate;
+
+ st->write_hdr = Z;
+ memcpy(st->write_buffer, update_buffer.buffer,sizeof U);
+ st->write_buffer_len = sizeof U;
+
+ ret = 0;
+ } else {
+ st->write_hdr = *result_hdr;
+
+ SIGDPRINT(Debug,14,(&Debug,
+ "prepare_write_message: [pid %d] socket=%d Preparing write %lu bytes (buffer size %lu)\n",
+ pid,socket,(unsigned long)buffer_len,(unsigned long)(st->write_buffer_size)));
+ if (buffer_len) {
+ memcpy(st->write_buffer,buffer,buffer_len);
+ st->write_buffer_len = buffer_len;
+ } else {
+ st->write_buffer_len = 0;
+ }
+
+ ret = 1;
+ }
+
+ st->write_pos = 0;
+ st->write_prepared = 1;
+ data.resolv = st;
+
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
+ change_action(socket,-1,resolv_read_message,resolv_write_message,
+ no_action_routine,
+ resolv_free_state,resolv_inc_state_refcount,data);
+ #else
+ ret = 0;
+ #endif
+ }
+
+ SIGDPRINT(Debug,14,(&Debug, "prepare_write_message=%d: [pid %d] socket=%d\n",
+ ret,pid,socket));
+
+ return ret;
+ }
+
+ void free_non_blocking_qm()
+ {
+ int mypid = getpid();
+ /* Free resources alloced by have_non_blocking_qm() */
+
+ if (process_list) {
+ size_t i;
+ int have_write = 0;
+
+ for (i = 0; i < process_list_len; i++) {
+
+ if (process_list[i]) {
+ int shut = 0;
+ if (RESOLV_PROCESS_magic != process_list[i]->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_non_blocking_qm",
+ "Bad magic number (resolv_process)",0);
+
+ DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%lu: pid=%d, state=%d",
+ (unsigned long)i,
+ process_list[i]->pid,
+ process_list[i]->state));
+
+ switch(process_list[i]->state) {
+ case ps_none: SIGDPRINT(Debug,12,(&Debug, " (none) ")); break;
+ case ps_forked: SIGDPRINT(Debug,12,(&Debug, " (forked) ")); + shut = 1;
+ break;
+ case ps_running: SIGDPRINT(Debug,12,(&Debug, " (running) ")); + shut = 1;
+ break;
+ case ps_shutdown: SIGDPRINT(Debug,12,(&Debug, " (shutdown)")); break;
+ case ps_exited: SIGDPRINT(Debug,12,(&Debug, " (exited) ")); break;
+ case ps_died: SIGDPRINT(Debug,12,(&Debug, " (died) ")); break;
+ }
+
+ if (-1 != process_list[i]->socket) {
+ DPRINT(Debug,12,(&Debug,", socket=%d",
+ process_list[i]->socket));
+ } else
+ shut = 0;
+
+ if (process_list[i]->message) {
+ if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_non_blocking_qm",
+ "Bad magic number (resolv_message_state)",0);
+
+ if (! process_list[i]->message->write_prepared) {
+ DPRINT(Debug,12,(&Debug,", write available"));
+ } else
+ shut = 0;
+ } else
+ shut = 0;
+ DPRINT(Debug,12,(&Debug,"\n"));
+
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
+ if (shut) {
+ int r;
+ struct resolv_query_hdr Z = NULL_resolv_query_hdr;
+ Z.senderpid = mypid;
+ Z.msg = qm_shutdown;
+
+ r = prepare_write_message(process_list[i]->message,process_list[i]->socket,
+ &Z,NULL,0);
+
+ if (!r) {
+ enum wait_for_status rz;
+
+ DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%d: Pausing for socket %d\n",
+ i,process_list[i]->socket));
+
+ if ((rz = wait_for_action_or_timeout(resolv_write_message,1)) > wait_for_none)
+ r = prepare_write_message(process_list[i]->message,process_list[i]->socket,
+ &Z,NULL,0);
+ else {
+ switch (rz) {
+ int err UNUSED_VAROK;
+ case wait_for_done: break;
+ case wait_for_none:
+ DPRINT(Debug,12,(&Debug,
+ "free_non_blocking_qm: unexpected result from wait_for_action_or_timeout\n"));
+ break;
+ case wait_for_error:
+ err = errno;
+ DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: wait errno=%d, %s\n",
+ err,strerror(err)));
+ break;
+ }
+ }
+ }
+
+ if (r)
+ have_write = 1;
+ }
+ #endif
+ }
+ }
+
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
+ if (have_write)
+ wait_for_action_or_timeout(resolv_write_message,0);
+ #endif
+
+ #ifdef BACKGROUD_PROCESSES
+ if (handle_sigchld) {
+ DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: checking for died processes.\n"));
+ sigchld_handler();
+ }
+
+ for (i = 0; i < process_list_len; i++) {
+
+ if (process_list[i]) {
+ if (RESOLV_PROCESS_magic != process_list[i]->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"free_non_blocking_qm",
+ "Bad magic number (resolv_process)",0);
+
+ if (process_list[i]->state >= ps_forked &&
+ process_list[i]->state <= ps_exited) {
+ int r;
+
+ DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%lu: pid=%d, ",
+ (unsigned long)i,
+ process_list[i]->pid));
+
+ r = kill (process_list[i]->pid,SIGTERM);
+ if (0 == r) {
+ int s;
+ int exit_code;
+ DPRINT(Debug,12,(&Debug,"sent SIGTERM, waiting for termination\n"));
+
+ s = wait_background_end(process_list[i]->pid,&exit_code);
+
+ DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: process #%lu: pid=%d, ",
+ (unsigned long)i,
+ process_list[i]->pid));
+ switch (s) {
+ case 1: DPRINT(Debug,12,(&Debug,"exited with status %d",exit_code)); break;
+ case 2: DPRINT(Debug,12,(&Debug,"no process")); break; + }
+ if (s < 0) {
+ DPRINT(Debug,12,(&Debug,"Dies with signal %d%s%s", + -s,
+ -s == SIGTERM ? " (SIGTERM)" : "", + -s == SIGINT ? " (SIGINT)" : ""
+ ));
+ }
+ } else if (-1 == r) {
+ int err UNUSED_VAROK = errno;
+ SIGDPRINT(Debug,12,(&Debug, "error %d: %s",
+ err,strerror(err)));
+ }
+ DPRINT(Debug,12,(&Debug,"\n"));
+ }
+ }
+ }
+ if (handle_sigchld) {
+ DPRINT(Debug,12,(&Debug,"free_non_blocking_qm: checking for died processes.\n"));
+ sigchld_handler();
+ }
+ #endif
+
+ for (i = 0; i < process_list_len; i++) {
+
+ if (process_list[i])
+ free_resolv_process(& (process_list[i]));
+ }
+ free(process_list);
+ process_list = NULL;
+
+ }
+ process_list_len = 0;
+
+ if (query_list) {
+ size_t i;
+
+ for (i = 0; i < query_list_len; i++) {
+ if (query_list[i])
+ free_resolv_query_item(& (query_list[i]));
+ }
+ free(query_list);
+ query_list = NULL;
+ }
+ query_list_len = 0;
+
+ }
+
+ #define MAX_PROCESS 2
+ static int prx_max_processes = MAX_PROCESS;
+
+ #define MAX_SKIP_PROCESS 5
+ static int prx_max_skip_process = MAX_SKIP_PROCESS;
+
+ static const int MAX_prx_processes = (MAX_PROCESS + MAX_SKIP_PROCESS > 100) ? (MAX_PROCESS + MAX_SKIP_PROCESS) : 100;
+
+
+
+ static void select_resolv_process P_((int pid,size_t querynum,const char *name));
+ static void select_resolv_process(pid,querynum,name)
+ int pid;
+ size_t querynum;
+ const char * name;
+ {
+ struct resolv_process * prx_static[MAX_PROCESS];
+ struct resolv_process ** prx = prx_static;
+ size_t prx_len = sizeof (prx_static) / sizeof (prx_static[0]);
+ size_t prx_count = 0;
+ size_t t;
+
+ DPRINT(Debug,16,(&Debug,
+ "select_resolv_process: prx_max_processes=%d prx_max_skip_process=%d process_list_len=%lu\n",
+ prx_max_processes,
+ prx_max_skip_process,
+ (unsigned long)process_list_len
+ ));
+
+ #if defined(RESOLV_SENDOK) && defined(RESOLV_SEQPACKET)
+ if (process_list) {
+ static size_t prindex = 0;
+ size_t previous_prindex = prindex;
+ size_t i;
+ int have_forked = 0;
+ int check_pipe = 0;
+
+ int skip_count = 0;
+
+ for (i = 0; i < process_list_len; i++) {
+ if (process_list[i]) {
+ if (RESOLV_PROCESS_magic != process_list[i]->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
+ "Bad magic number (resolv_process)",0);
+
+ if (ps_forked == process_list[i]->state &&
+ -1 != process_list[i]->pid) {
+ DPRINT(Debug,14,(&Debug, "select_resolv_process: process index %lu (pid %d) have state forked\n",
+ (unsigned long)i,process_list[i]->pid));
+ have_forked = 1;
+ break;
+ } else if (ps_shutdown < process_list[i]->state &&
+ -1 != process_list[i]->pid) {
+ DPRINT(Debug,14,(&Debug, "select_resolv_process: process index %lu (pid %d) have process ended",
+ (unsigned long)i,process_list[i]->pid));
+ if (process_list[i]->message) {
+ if (RESOLV_MESSAGE_STATE_magic != process_list[i]->message->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
+ "Bad magic number (resolv_message_state)",0); +
+ if (process_list[i]->message->broken_pipe) {
+ DPRINT(Debug,14,(&Debug, "-- broken pipe (or EOF)"));
+ } else {
+ DPRINT(Debug,14,(&Debug, "-- EOF not read yet"));
+ check_pipe = 1;
+ }
+ }
+ DPRINT(Debug,14,(&Debug, "\n"));
+ }
+ }
+ }
+
+ if (have_forked) {
+ DPRINT(Debug,14,(&Debug, "select_resolv_process: [pid %d] waiting running message from forked process.\n",
+ pid));
+ wait_for_action_or_timeout(resolv_read_message,1);
+ } else if (check_pipe) {
+ DPRINT(Debug,14,(&Debug, "select_resolv_process: [pid %d] polling EOF from pipe\n",
+ pid));
+ wait_for_action_or_timeout(resolv_read_message,0);
+ }
+
+ do {
+ prindex++;
+
+ if (prindex >= process_list_len) {
+ size_t X UNUSED_VAROK = prindex;
+
+ prindex = 0;
+ DPRINT(Debug,14,(&Debug, "select_resolv_process: [pid %d] query %lu %s: reached process index %lu -- wrapping to %lu\n",
+ pid,
+ (unsigned long)querynum,
+ name,
+ (unsigned long)X,(unsigned long)prindex));
+ }
+
+ if (prindex < process_list_len &&
+ prx_count < prx_max_processes) {
+
+ if (prx_count > prx_len)
+ panic("RESOLV PANIC",__FILE__,__LINE__,
+ "select_resolv_process",
+ "Overflow",0);
+ else if (prx_count == prx_len) {
+
+ if (prx == prx_static &&
+ prx_max_processes > prx_count) {
+ size_t a;
+
+ DPRINT(Debug,14,(&Debug, "select_resolv_process: allocating list %lu",
+ (unsigned long)prx_len));
+
+ prx_len = prx_max_processes;
+ if (prx_len > process_list_len+1 &&
+ process_list_len+1 > prx_count) {
+ DPRINT(Debug,14,(&Debug, " (max %d)",
+ prx_max_processes));
+ prx_len = process_list_len+1;
+ }
+
+ DPRINT(Debug,14,(&Debug, " => %lu\n",
+ (unsigned long)prx_len));
+
+ prx = safe_calloc(prx_len,sizeof(prx[0]));
+ for (a = 0;
+ a < prx_count &&
+ a < sizeof (prx_static) / sizeof (prx_static[0]);
+ a++)
+ prx[a] = prx_static[a];
+
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: allocating list %lu -- something wrong\n",
+ (unsigned long)prx_len));
+ break;
+ }
+ }
+
+ if (process_list[prindex]) {
+
+ if (RESOLV_PROCESS_magic != process_list[prindex]->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
+ "Bad magic number (resolv_process)",0);
+
+ if (resolv_process_ok(process_list[prindex])) {
+
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: [pid %d] query %lu %s: process index %lu is available (pid %d, socket %d)\n",
+ pid,
+ (unsigned long)querynum,
+ name,
+ (unsigned long)prindex,
+ process_list[prindex]->pid,
+ process_list[prindex]->socket));
+
+ if (process_list[prindex]->message) {
+ if (RESOLV_MESSAGE_STATE_magic != process_list[prindex]->message->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
+ "Bad magic number (resolv_message_state)",0);
+
+ if (process_list[prindex]->message->broken_pipe) { + int r;
+ int may_delete = 0;
+
+ DPRINT(Debug,14,(&Debug, "select_resolv_process: process #%lu: (pid %d, socket %d) -- broken pipe (or EOF)",
+ (unsigned long)prindex,
+ process_list[prindex]->pid,
+ process_list[prindex]->socket));
+
+ r = kill(process_list[prindex]->pid,
+ SIGTERM);
+
+ if (0 == r) {
+ int s;
+ int exit_code;
+
+ DPRINT(Debug,14,(&Debug,"; sent SIGTERM, waiting for termination\n"));
+
+ s = wait_background_end(process_list[prindex]->pid,&exit_code);
+
+ DPRINT(Debug,14,(&Debug,"select_resolv_process: process #%lu: pid=%d, ",
+ (unsigned long)prindex,
+ process_list[prindex]->pid));
+ switch (s) {
+ case 1:
+ DPRINT(Debug,14,(&Debug,"exited with status %d",exit_code));
+ may_delete = 1;
+ break;
+ case 2: DPRINT(Debug,14,(&Debug,"no process"));
+ may_delete = 1;
+ break;
+ }
+ if (s < 0) {
+ DPRINT(Debug,14,(&Debug,"Dies with signal %d%s%s",
+ -s,
+ -s == SIGTERM ? " (SIGTERM)" : "",
+ -s == SIGINT ? " (SIGINT)" : ""
+ ));
+ may_delete = 1;
+ }
+ } else if (-1 == r) {
+ int err = errno;
+ SIGDPRINT(Debug,14,(&Debug, "; tried send SIGTERM, got error %d: %s",
+ err,strerror(err)));
+
+ if (ESRCH == err)
+ may_delete = 1;
+ }
+
+ if (may_delete)
+ goto cleanup_process;
+
+ DPRINT(Debug,14,(&Debug,"\n"));
+
+ goto skip_it;
+ }
+
+ if (process_list[prindex]->message->write_prepared ||
+ process_list[prindex]->message->query_in_progress) {
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: process #%lu: (pid %d, socket %d)%s%s\n",
+ (unsigned long)prindex,
+ process_list[prindex]->pid,
+ process_list[prindex]->socket, + process_list[prindex]->message->write_prepared ?
+ " -- write prepared (busy)" : "",
+ process_list[prindex]->message->query_in_progress ?
+ " -- query in progress (busy)" : "",
+ process_list[prindex]->pid,
+ process_list[prindex]->socket));
+
+ if (skip_count >= prx_max_skip_process) {
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: Already %d skipped, using anyway\n",
+ skip_count));
+ } else {
+ skip_count ++;
+ goto skip_it;
+ }
+ }
+
+ }
+
+ prx[prx_count] = process_list[prindex];
+ inc_resolv_process_refcount(prx[prx_count]);
+ prx_count++;
+ } else if (ps_shutdown < process_list[prindex]->state &&
+ -1 != process_list[prindex]->pid) {
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: [pid %d] query %lu %s: process index %lu not available (pid %d, socket %d)",
+ pid,
+ (unsigned long)querynum,
+ name,
+ (unsigned long)prindex,
+ process_list[prindex]->pid,
+ process_list[prindex]->socket));
+
+ if (process_list[prindex]->message) {
+ if (RESOLV_MESSAGE_STATE_magic != process_list[prindex]->message->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
+ "Bad magic number (resolv_message_state)",0);
+
+ if (process_list[prindex]->message->broken_pipe) { + DPRINT(Debug,14,(&Debug," -- broken pipe (or EOF)"));
+ goto cleanup_process;
+ }
+ DPRINT(Debug,14,(&Debug,", ignored now\n"));
+
+ } else
+ goto cleanup_process;
+ } else if (-1 == process_list[prindex]->pid) {
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: [pid %d] query %lu %s: process index %lu not available (no process?)",
+ pid,
+ (unsigned long)querynum,
+ name,
+ (unsigned long)prindex));
+
+ cleanup_process:
+ SIGDPRINT(Debug,14,(&Debug, "; may delete process #%lu index entry\n",
+ (unsigned long)prindex));
+
+ free_resolv_process(& (process_list[prindex]));
+
+ }
+ } else {
+ DPRINT(Debug,15,(&Debug,
+ "select_resolv_process: [pid %d] query %lu %s: process index %lu unused entry\n",
+ pid,
+ (unsigned long)querynum,
+ name,
+ (unsigned long)prindex));
+ }
+ }
+
+ skip_it: ;
+
+ } while (prindex != previous_prindex &&
+ prx_count < prx_max_processes);
+ }
+
+ if (prx_count < prx_max_processes &&
+ prx_count < prx_len) {
+
+ prx[prx_count] = give_resolv_process(pid);
+
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: [pid %d] query %lu %s: added process (pid %d, socket %d)\n",
+ pid,
+ (unsigned long)querynum,
+ name,
+ prx[prx_count]->pid,
+ prx[prx_count]->socket));
+
+ inc_resolv_process_refcount(prx[prx_count]);
+ prx_count++;
+ }
+
+ for (t = 0; t < prx_count; t++) {
+
+ union action_routine_data data;
+
+ if (RESOLV_PROCESS_magic != prx[t]->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process",
+ "Bad magic number (resolv_process)",0);
+
+ if (prx[t]->message) {
+ if (RESOLV_MESSAGE_STATE_magic != prx[t]->message->magic)
+ panic("RESOLV PANIC",__FILE__,__LINE__,"select_resolv_process", + "Bad magic number (resolv_message_state)",0);
+
+ } else if (! prx[t]->message) {
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: [pid %d] query %lu %s: adding message state for pid %d (socket %d)\n",
+ pid,
+ (unsigned long)querynum,
+ name,
+ prx[t]->pid,
+ prx[t]->socket));
+ prx[t]->message =
+ new_resolv_message_state(pid /* my pid -- senderpid */);
+ }
+
+ data.resolv = prx[t]->message;
+
+ change_action(prx[t]->socket,-1,resolv_read_message,resolv_write_message,
+ no_action_routine,
+ resolv_free_state,resolv_inc_state_refcount,data);
+
+ DPRINT(Debug,14,(&Debug,
+ "select_resolv_process: [pid %d] query %lu %s: scheduled write for pid %d socket %d\n",
+ pid,
+ (unsigned long)querynum,
+ name,
+ prx[t]->pid,
+ prx[t]->socket));
+
+ free_resolv_process(& prx[t]);
+ }
+ #endif
+
+ if (prx != prx_static)
+ free(prx);
+ }
+
+ static struct resolv_query_item *query_one_name P_((struct resolv_cache * record,
+ const char * name,
+ const char * domain,
+ const struct schedule_timelimit * now,
+ ns_type q_type,
+ enum looking_up * looking_up,
+ int * err_p,
+ int is_search
+ ));
+ static struct resolv_query_item *query_one_name(record,name,domain,now,q_type,
+ looking_up,err_p, is_search)
+ struct resolv_cache * record;
+ const char * name;
+ const char * domain;
+ const struct schedule_timelimit * now;
+ ns_type q_type;
+ enum looking_up * looking_up;
+ int * err_p;
+ int is_search;
+ {
+ struct resolv_query_item * ret = NULL;
+ int pid = getpid();
+
+ static size_t querynum = 0;
+ size_t previous_querynum = querynum;
+
+ char * name_buffer = NULL;
+ size_t qsize = RESOLV_BUFSIZE;
+ int retry = 0;
+
+ *err_p = 0;
+
+ do {
+
+ querynum++;
+ if (querynum >= query_list_len) {
+ size_t X UNUSED_VAROK = querynum;
+
+ querynum = 0;
+ DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] name %s domain %s -- reached query number %lu -- wrapping to %lu\n",
+ pid,name,
+ domain ? domain : "<none>",
+ (unsigned long)X,(unsigned long)querynum));
+ }
+
+ /* 0 is not used */
+ if (querynum > 0 && querynum < query_list_len &&
+ ! query_list[querynum]) {
+
+ DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] name %s domain %s -- query number %lu is available\n",
+ pid,name,
+ domain ? domain : "<none>",(unsigned long)querynum));
+ break;
+ }
+
+
+ } while (querynum != previous_querynum);
+
+ if (querynum < 1 || querynum >= query_list_len ||
+ query_list[querynum]) {
+ size_t nsize = query_list_len +3;
+ /* Increment query list */
+
+ query_list = safe_array_realloc(query_list,nsize,sizeof (query_list[0]));
+
+ DPRINT(Debug,14,(&Debug,
+ "query_one_name: [pid %d] name %s domain %s -- enlarging query_list %ld => %ld\n",
+ pid,name,
+ domain ? domain : "<none>",
+ (unsigned long)query_list_len, (unsigned long)nsize)); +
+ querynum = query_list_len;
+ if (!querynum)
+ querynum++;
+
+ while (query_list_len < nsize)
+ query_list[query_list_len++] = NULL;
+
+ }
+
+ if (querynum < 1 || querynum >= query_list_len ||
+ query_list[querynum])
+ panic("RESOLV PANIC",__FILE__,__LINE__,"query_one_name",
+ "Bad magic number (resolv_process) querynum",0);
+
+
+ ret = query_list[querynum] = new_resolv_query_item(querynum,name);
+ inc_resolv_query_item_recount(ret);
+ ret->query_time = *now;
+ ret->query_buffer = new_resolv_message();
+ ret->query_hdr = new_resolv_query_hdr();
+ if (is_search) {
+ DPRINT(Debug,14,(&Debug,
+ "query_one_name: [pid %d] name %s domain %s -- setting 'is search'\n",
+ pid,name,
+ domain ? domain : "<none>"));
+
+ ret->is_search = 1;
+ }
+
+ ret->answer_buffer = new_resolv_message();
+ resize_resolv_message(ret->answer_buffer,RESOLV_BUFSIZE);
+ ret->answer_hdr = new_resolv_query_hdr();
+ ret->cache_answer_in = record;
+ inc_resolv_cache_refcount(ret->cache_answer_in);
+ if (looking_up)
+ ret->looking_up = *looking_up;
+
+ if (domain && domain[0]) {
+ size_t a = strlen(name);
+ size_t d = strlen(domain);
+ size_t len = a+d+2;
+ size_t z = a;
+
+ name_buffer = safe_malloc(len);
+
+ memcpy(name_buffer,name,a);
+ if ('.' != domain[0])
+ name_buffer[z++] = '.';
+ memcpy(name_buffer+z,domain,d);
+ name_buffer[z+d] = '\0';
+
+ DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu: name %s domain %s => %s\n",
+ pid,
+ (unsigned long)querynum,
+ name,
+ domain ? domain : "<none>",
+ name_buffer));
+
+ }
+
+ do {
+ int qlen;
+
+ resize_resolv_message(ret->query_buffer,qsize);
+
+ DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: query buffer size %u\n",
+ pid,
+ (unsigned long)querynum,
+ name_buffer ? name_buffer : name,
+ (unsigned) ret->query_buffer->message_size));
+
+ errno = 0;
+
+ qlen = res_mkquery(QUERY,name_buffer ? name_buffer : name,
+ ns_c_in,q_type,
+ NULL,0 /* Only used with IQUERY */,
+ NULL /* Only used with dynamic update */,
+ ret->query_buffer->message,
+ ret->query_buffer->message_size);
+
+ if (qlen < 0 ) {
+ int err = errno;
+
+ DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: res_mkquery: err = %d (%s)\n",
+ pid,
+ (unsigned long)querynum,
+ name_buffer ? name_buffer : name,
+ err,strerror(err)));
+
+ if (EMSGSIZE == err && qsize < MAX_resolv_bufsize) {
+
+ if (qsize < sizeof (struct resolv_sizeupdate))
+ qsize = sizeof (struct resolv_sizeupdate);
+ else
+ qsize <<=1;
+
+ if (qsize > MAX_resolv_bufsize)
+ qsize = MAX_resolv_bufsize;
+
+ retry = 1;
+
+ } else {
+ *err_p = err;
+
+ free_resolv_query_item(&ret);
+ goto failure;
+
+ }
+ } else if (qlen <= USHRT_MAX) {
+ ret->query_buffer->message_len = qlen;
+
+
+ DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: res_mkquery: message len %u\n",
+ pid,
+ (unsigned long)querynum,
+ name_buffer ? name_buffer : name,
+ (unsigned) ret->query_buffer->message_len));
+
+ retry = 0;
+ } else {
+ DPRINT(Debug,14,(&Debug,
+ "query_one_name: [pid %d] query %lu %s: query len %d, too long\n",
+ pid,
+ (unsigned long)querynum,
+ name_buffer ? name_buffer : name,
+ qlen));
+ *err_p = EMSGSIZE;
+
+ free_resolv_query_item(&ret);
+ goto failure;
+ }
+
+ if (retry) {
+ DPRINT(Debug,14,(&Debug, "query_one_name: [pid %d] query %lu %s: res_mkquery: retrying with size %lu\n",
+ pid,
+ (unsigned long)querynum,
+ name_buffer ? name_buffer : name,
+ (unsigned long)qsize));
+ }
+
+ } while (retry);
+
+ ret->query_hdr->buflen = ret->query_buffer->message_len;
+ ret->query_hdr->querynum = querynum;
+ ret->query_hdr->senderpid = pid;
+ ret->query_hdr->msg = qm_query;
+
+ if (!parse_resolv_message1(ret->query_buffer,err_p)) {
[continued in next message]
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)