static void q_initd_run(struct runqueue *q, struct runqueue_task *t) { struct initd *s = container_of(t, struct initd, proc.task); int pipefd[2]; pid_t pid; DEBUG(2, "start %s %s \n", s->file, s->param); if (pipe(pipefd) == -1) { ERROR("Failed to create pipe\n"); return; } pid = fork(); if (pid < 0) return; if (pid) { close(pipefd[1]); s->fd.stream.string_data = true, s->fd.stream.notify_read = pipe_cb, runqueue_process_add(q, &s->proc, pid); ustream_fd_init(&s->fd, pipefd[0]); return; } close(pipefd[0]); dup2(pipefd[1], STDOUT_FILENO); dup2(pipefd[1], STDERR_FILENO); execlp(s->file, s->file, s->param, NULL); exit(1); }
/* * Here we fork and run the scripts in the child process. * The parent process just monitors the child process. */ static void task_scripts_run(struct runqueue *q, struct runqueue_task *t) { char cmd[500]; int len = 0; struct scripts_proc* scr = container_of(t, struct scripts_proc, proc.task); struct ping_intf* pi = scr->intf; char* state_str = (scr->state == ONLINE ? "online" : "offline"); pid_t pid = fork(); if (pid < 0) { printlog(LOG_ERR, "Run scripts fork failed!"); return; } else if (pid > 0) { /* parent process: monitor until child has finished */ runqueue_process_add(q, &scr->proc, pid); return; } /* child process */ len = snprintf(cmd, sizeof(cmd), "export INTERFACE=\"%s\"; export DEVICE=\"%s\"; export GLOBAL=\"%s\"; " "for hook in /etc/pingcheck/%s.d/*; do [ -r \"$hook\" ] && sh $hook; done", pi->name, pi->device, get_global_status_str(), state_str); if (len <= 0 || (unsigned int)len >= sizeof(cmd)) { // error or truncated printlog(LOG_ERR, "Run scripts commands truncated!"); _exit(EXIT_FAILURE); } printlog(LOG_NOTICE, "Running '%s' scripts for '%s'", state_str, pi->name); int ret = execlp("/bin/sh", "/bin/sh", "-c", cmd, NULL); if (ret == -1) { printlog(LOG_ERR, "Run scripts exec error!"); _exit(EXIT_FAILURE); } }