/* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe) { RESOLVED_IP_REC rec; const char *errorstr; #ifndef WIN32 int pid; #endif g_return_val_if_fail(addr != NULL, FALSE); #ifndef WIN32 pid = fork(); if (pid > 0) { /* parent */ pidwait_add(pid); return pid; } if (pid != 0) { /* failed! */ g_warning("net_connect_thread(): fork() failed! " "Using blocking resolving"); } #endif /* child */ memset(&rec, 0, sizeof(rec)); rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6); if (rec.error == 0) { errorstr = NULL; } else { errorstr = net_gethosterror(rec.error); rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1; } g_io_channel_write_block(pipe, &rec, sizeof(rec)); if (rec.errlen != 0) g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); #ifndef WIN32 if (pid == 0) _exit(99); #endif /* we used blocking lookup */ return 0; }
static void sig_session_restore(CONFIG_REC *config) { CONFIG_NODE *node; GSList *tmp; char **pids, **pid; /* restore servers */ node = config_node_traverse(config, "(servers", FALSE); if (node != NULL) { tmp = config_node_first(node->value); for (; tmp != NULL; tmp = config_node_next(tmp)) session_restore_server(tmp->data); } /* restore pids (so we don't leave zombies) */ pids = g_strsplit(config_node_get_str(config->mainnode, "pids", ""), " ", -1); for (pid = pids; *pid != NULL; pid++) pidwait_add(atoi(*pid)); g_strfreev(pids); }
/* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_lookup) { RESOLVED_IP_REC rec; const char *errorstr; int pid; int len; g_return_val_if_fail(addr != NULL, FALSE); pid = fork(); if (pid > 0) { /* parent */ pidwait_add(pid); return pid; } if (pid != 0) { /* failed! */ g_warning("net_connect_thread(): fork() failed! " "Using blocking resolving"); } /* child */ srand(time(NULL)); memset(&rec, 0, sizeof(rec)); rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6); if (rec.error == 0) { errorstr = NULL; if (reverse_lookup) { /* reverse lookup the IP, ignore any error */ if (rec.ip4.family != 0) net_gethostbyaddr(&rec.ip4, &rec.host4); if (rec.ip6.family != 0) net_gethostbyaddr(&rec.ip6, &rec.host6); } } else { errorstr = net_gethosterror(rec.error); rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1; } g_io_channel_write_block(pipe, &rec, sizeof(rec)); if (rec.errlen != 0) g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen); else { if (rec.host4) { len = strlen(rec.host4) + 1; g_io_channel_write_block(pipe, (void *) &len, sizeof(int)); g_io_channel_write_block(pipe, (void *) rec.host4, len); } if (rec.host6) { len = strlen(rec.host6) + 1; g_io_channel_write_block(pipe, (void *) &len, sizeof(int)); g_io_channel_write_block(pipe, (void *) rec.host6, len); } } if (pid == 0) _exit(99); /* we used blocking lookup */ return 0; }
static void process_exec(PROCESS_REC *rec, const char *cmd) { const char *shell_args[4] = { "/bin/sh", "-c", NULL, NULL }; char **args; int in[2], out[2]; int n; if (pipe(in) == -1) return; if (pipe(out) == -1) return; shell_args[2] = cmd; rec->pid = fork(); if (rec->pid == -1) { /* error */ close(in[0]); close(in[1]); close(out[0]); close(out[1]); return; } if (rec->pid != 0) { /* parent process */ GIOChannel *outio = g_io_channel_unix_new(in[1]); rec->in = g_io_channel_unix_new(out[0]); rec->out = net_sendbuffer_create(outio, 0); close(out[1]); close(in[0]); pidwait_add(rec->pid); return; } /* child process, try to clean up everything */ setsid(); setuid(getuid()); setgid(getgid()); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_DFL); putenv("TERM=tty"); /* set stdin, stdout and stderr */ dup2(in[0], STDIN_FILENO); dup2(out[1], STDOUT_FILENO); dup2(out[1], STDERR_FILENO); /* don't let child see our files */ for (n = 3; n < 256; n++) close(n); if (rec->shell) { execvp(shell_args[0], (char **) shell_args); fprintf(stderr, "Exec: /bin/sh: %s\n", g_strerror(errno)); } else { args = g_strsplit(cmd, " ", -1); execvp(args[0], args); fprintf(stderr, "Exec: %s: %s\n", args[0], g_strerror(errno)); } _exit(-1); }