static void run_ras(struct ast_channel *chan, char *args) { pid_t pid; int status; int res; int signalled = 0; struct dahdi_bufferinfo savebi; int x; res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi); if(res) { ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name); return; } pid = spawn_ras(chan, args); if (pid < 0) { ast_log(LOG_WARNING, "Failed to spawn RAS\n"); } else { for (;;) { res = wait4(pid, &status, WNOHANG, NULL); if (!res) { /* Check for hangup */ if (ast_check_hangup(chan) && !signalled) { ast_debug(1, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid); kill(pid, SIGTERM); signalled=1; } /* Try again */ sleep(1); continue; } if (res < 0) { ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno)); } if (WIFEXITED(status)) { ast_verb(3, "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { ast_verb(3, "RAS on %s terminated with signal %d\n", chan->name, WTERMSIG(status)); } else { ast_verb(3, "RAS on %s terminated weirdly.\n", chan->name); } /* Throw back into audio mode */ x = 1; ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x); /* Restore saved values */ res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi); if (res < 0) { ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name); } break; } } }
static int load_kext(void) { int result = -1; int pid, terminated_pid; union wait status; long major; char *load_prog_path; major = fuse_os_version_major_np(); if (major < OSXFUSE_MIN_DARWIN_VERSION) { /* This is not a supported version of macOS */ return EINVAL; } load_prog_path = OSXFUSE_LOAD_PROG; if (!load_prog_path) { fprintf(stderr, "fuse: load program missing\n"); goto Return; } pid = fork(); if (pid == 0) { /* Drop saved set-user-ID */ setuid(getuid()); setgid(getgid()); result = execl(load_prog_path, load_prog_path, NULL); /* exec failed */ check_noerr_string(result, strerror(errno)); _exit(1); } require_action(pid != -1, Return, result = errno); while ((terminated_pid = wait4(pid, (int *)&status, 0, NULL)) < 0) { /* retry if EINTR, else break out with error */ if (errno != EINTR) { break; } } if ((terminated_pid == pid) && (WIFEXITED(status))) { result = WEXITSTATUS(status); } else { result = -1; } Return: check_noerr_string(result, strerror(errno)); return result; }
RETSIGTYPE RedProc_SigChld(int arg) { int status; // fprintf(stderr,"libreduce: receiving SIGCHLD\n"); if (wait4(process->processId,&status,WNOHANG,NULL) == process->processId) { fprintf(stderr,"libreduce: receiving SIGCHLD\n"); fprintf(stderr,"libreduce: Reduce has stopped or exited - Quitting\n"); exit(SIGCHLD); } }
int my_wait(pid_t pid) { int status; if (wait4(pid, &status, WUNTRACED, NULL) <= -1) return (FAILURE); if (WIFEXITED(status)) return (FAILURE); return (status); }
// // waits for children. options is passed to the wait4 calls // so if you don't want this call to block, call the function // with WNOHANG. Otherwise, specify 0 which will wait for all // chilren void wait_for_child(int options) { pid_t cpid; int ret; while (started_counter!= finished_counter && 0 != (cpid = wait4(-1, &ret, options, NULL))) { finished_counter++; std::string ip = started_processes[cpid]; finished_processes[ip] = WEXITSTATUS(ret); } }
int main() { puts("Parent started"); pid_t pid; pid = fork(); if(pid < 0) { puts("fork() failed"); return(-1); } if(pid == 0) { /* child process */ ptrace(PTRACE_TRACEME, 0, 0, 0); puts("Child sleeping..."); sleep(1); puts("Child exec..."); execlp("./target", "target", NULL); } else { printf("Child PiD == %d\n", pid); int status = 0; struct rusage ru; wait4(pid, &status, 0, &ru); long rax_rt = ptrace(PTRACE_PEEKUSER, pid, 8 * RAX, 0); printf("Child execve() returned with %ld\n",rax_rt); ptrace(PTRACE_SYSCALL, pid, 0, 0); int intocall=1; while(1) { wait4(pid, &status, 0, &ru); if (WIFEXITED(status)){ puts("Child Exited"); break; } long _ORIG_RAX = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, 0); long _RAX = ptrace(PTRACE_PEEKUSER, pid, 8 * RAX, 0); if(intocall) { printf("Entering SYSCALL %ld .... ", _ORIG_RAX); intocall = 0; } else { printf("Exited with %ld\n",_RAX); intocall = 1; } ptrace(PTRACE_SYSCALL, pid, 0, 0); } } }
void lls(char **tab) { int id; id = fork(); if (id == 0) execv("/bin/ls", tab); else wait4(id, 0, 0, 0); }
static void sigchld(int sig) { int status; (void)sig; if (wait4(child, &status, WNOHANG, NULL) == child && (WIFEXITED(status) || WIFSIGNALED(status))) { child = 0; } }
int ptlib_linux_wait( pid_t *pid, int *status, ptlib_extra_data *data, int async ) { *pid=wait4(-1, status, (async?WNOHANG:0)|__WALL, data ); if( async && *pid==0 ) { errno=EAGAIN; *pid=-1; } return *pid!=-1; }
/* * Execute and wait for external command */ int exec_cmd(struct cmd_context *cmd, const char *const argv[], int *rstatus) { pid_t pid; int status; char buf[PATH_MAX * 2]; log_verbose("Executing: %s", _verbose_args(argv, buf, sizeof(buf))); if ((pid = fork()) == -1) { log_error("fork failed: %s", strerror(errno)); return 0; } if (!pid) { /* Child */ reset_locking(); dev_close_all(); /* FIXME Fix effect of reset_locking on cache then include this */ /* destroy_toolcontext(cmd); */ /* FIXME Use execve directly */ execvp(argv[0], (char **const) argv); log_sys_error("execvp", argv[0]); _exit(errno); } if (rstatus) *rstatus = -1; /* Parent */ if (wait4(pid, &status, 0, NULL) != pid) { log_error("wait4 child process %u failed: %s", pid, strerror(errno)); return 0; } if (!WIFEXITED(status)) { log_error("Child %u exited abnormally", pid); return 0; } if (WEXITSTATUS(status)) { if (rstatus) { *rstatus = WEXITSTATUS(status); log_verbose("%s failed: %u", argv[0], *rstatus); } else log_error("%s failed: %u", argv[0], WEXITSTATUS(status)); return 0; } if (rstatus) *rstatus = 0; return 1; }
static void handle_sigchld(int sig __unused) { int pid, status; pid = wait4(-1, &status, WNOHANG, (struct rusage*)0); if (!pid) syslog(LOG_ERR, "Phantom SIGCHLD??"); else if (status == 0) { if (debug) syslog(LOG_DEBUG, "Child %d exited OK", pid); } else syslog(LOG_ERR, "Child %d failed with status %d", pid, WEXITSTATUS(status)); }
int main (int argc, char* argv[]) { int cmd_start_index; int i; pid_t pid, hardlimit_monitor; init_default_limits (); cmd_start_index = parse_args (argc, argv); /* be safe on the timehard! */ if (limit_timehard < 1 + (int) ceil (limit_time)) limit_timehard = 1 + (int) ceil (limit_time); /* close inherited file descriptors. Is there a better way? */ for (i = 3; i < (1<<16); i++) close (i); pid = fork(); if (pid==0) { return subprocess (argc - cmd_start_index, argv + cmd_start_index); } hardlimit_monitor = fork (); if (hardlimit_monitor == 0) { sleep (6*limit_timehard); /* if I reached here, then the main process is still running, * upto some race condition possibilitiy */ //fprintf (stderr, "Severe hardlimit (%d) reached. Possibly \ malicious, or overloaded system.\n", 6*limit_timehard); kill (pid, 9); return 0; } int status; struct rusage usage ; /* * Correctness: Pid dies on its own or, hardlimit_monitor process * kills it. In both cases, this works, except perhaps the Pid * process can be called for kill twice. */ wait4(pid,&status, 0, &usage); //Wait for child to terminate kill (hardlimit_monitor, 9); waitpid (hardlimit_monitor, NULL, 0); // lets output the limits. fflush(stderr) ; /* ordering of output of child and parent should be right */ double usertime = (float) (usage.ru_utime.tv_sec) + ((float) usage.ru_utime.tv_usec)/1000000 ; //fprintf(stderr, "Usertime: %lf\n", usertime);
ATF_TC_BODY(wait4_options, tc) { size_t i = 0; int o; while((o = get_options4(i++)) != -1) { printf("Testing wait4(2) with options %x\n", o); ATF_REQUIRE_ERRNO(ECHILD, wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1); } }
int main(int argc, char *argv[]) { int fd1; int fd2; int exitcode = 1; char filename[256]; snprintf(filename, sizeof(filename), "/tmp/valgrind-file-locking-test.%ld", (long) getpid()); unlink(filename); if ((fd1 = open_lock_and_map("parent", filename)) >= 0) { pid_t fork_result; fork_result = fork(); switch (fork_result) { case -1: perror("fork"); break; case 0: /* child */ fd2 = open_lock_and_map("child", filename); if (fd2 >= 0) { close(fd2); } exit(0); break; default: /* parent */ { int child_status; int wait_result; wait_result = wait4(fork_result, &child_status, 0, 0); assert(wait_result >= 0); } } } close(fd1); unlink(filename); fprintf(stderr, "Test finished.\n"); return exitcode; }
int system(const char *command) { pid_t pid; int pstat; struct sigaction ign, intact, quitact; sigset_t newsigblock, oldsigblock; if (!command) /* just checking... */ return (1); /* * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save existing * signal dispositions. */ ign.sa_handler = SIG_IGN; (void) sigemptyset(&ign.sa_mask); ign.sa_flags = 0; (void) sigaction(SIGINT, &ign, &intact); (void) sigaction(SIGQUIT, &ign, &quitact); (void) sigemptyset(&newsigblock); (void) sigaddset(&newsigblock, SIGCHLD); (void) sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); switch (pid = fork()) { case -1: /* error */ break; case 0: /* child */ /* * Restore original signal dispositions and exec the command. */ (void) sigaction(SIGINT, &intact, NULL); (void) sigaction(SIGQUIT, &quitact, NULL); (void) sigprocmask(SIG_SETMASK, &oldsigblock, NULL); execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL); _exit(127); default: /* parent */ do { pid = wait4(pid, &pstat, 0, (struct rusage *) 0); } while (pid == -1 && errno == EINTR); break; } (void) sigaction(SIGINT, &intact, NULL); (void) sigaction(SIGQUIT, &quitact, NULL); (void) sigprocmask(SIG_SETMASK, &oldsigblock, NULL); return (pid == -1 ? -1 : pstat); }
int main(int argc, char *argv[], char *const envp[]) { pid_t child_pid, w; int status; char *childargv[] = {"make", "-s", "--no-print-directory", "-f", MAKEFILE, MAKEFILE_TARGET, NULL}; if (argc != 4) { fprintf(stderr, "Usage: ./tracker <timeout_seconds> <input_file> <output_file> \n"); exit(EXIT_FAILURE); } float ftimeout; int timeout; sscanf(argv[1], "%f", &ftimeout); timeout = (int)ceil(ftimeout); child_pid = fork(); if (-1 == child_pid) { fprintf(stderr, "Error in fork(): %s\n", strerror(errno)); exit(EXIT_FAILURE); } else if (0 == child_pid) { if (setup_job(timeout, argv[2], argv[3])) { exit(EXIT_FAILURE); } execve("/usr/bin/make", childargv, envp); /* should not be here */ fprintf(stderr, "Error in execve(): %s\n", strerror(errno)); exit(EXIT_FAILURE); } else { struct rusage accounting; w = wait4(child_pid, &status, 0, &accounting); if (WEXITSTATUS(status)) { /* we got an error */ return WEXITSTATUS(status); } else { /* print some stats */ int seconds = (int)accounting.ru_utime.tv_sec + (int)accounting.ru_stime.tv_sec; int useconds = (int)accounting.ru_utime.tv_usec + (int)accounting.ru_stime.tv_usec; if (seconds == timeout - 1) { int utimeout = (int)((ftimeout - (float)(timeout - 1)) * UFACT); if (useconds - utimeout > UERR) { fprintf(stderr, "CPU time limit exceeded\n"); return 1; } } /* success */ float ftime = (float)seconds + (float)useconds / UFACT; fprintf(stdout, "time: %f seconds\n", ftime); } } return 0; }
/* we run at @regs->ip */ static int parasite_trap(struct parasite_ctl *ctl, pid_t pid, user_regs_struct_t *regs, struct thread_ctx *octx) { siginfo_t siginfo; int status; int ret = -1; /* * Most ideas are taken from Tejun Heo's parasite thread * https://code.google.com/p/ptrace-parasite/ */ if (wait4(pid, &status, __WALL, NULL) != pid) { pr_perror("Waited pid mismatch (pid: %d)", pid); goto err; } if (!WIFSTOPPED(status)) { pr_err("Task is still running (pid: %d)\n", pid); goto err; } if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo)) { pr_perror("Can't get siginfo (pid: %d)", pid); goto err; } if (ptrace_get_regs(pid, regs)) { pr_perror("Can't obtain registers (pid: %d)", pid); goto err; } if (WSTOPSIG(status) != SIGTRAP || siginfo.si_code != ARCH_SI_TRAP) { pr_debug("** delivering signal %d si_code=%d\n", siginfo.si_signo, siginfo.si_code); pr_err("Unexpected %d task interruption, aborting\n", pid); goto err; } /* * We've reached this point if int3 is triggered inside our * parasite code. So we're done. */ ret = 0; err: if (restore_thread_ctx(pid, octx)) ret = -1; return ret; }
/* Routine to wait for child to complete */ void *wait4_child_thread(void *arg) { int err; int child_stat; wait4(-1, &child_stat, 0, NULL); if ((err = pthread_cond_broadcast(&cv)) != 0) { fprintf(stderr, "pthread_cond_broadcast: %s\n", strerror(err)); exit(1); } return (NULL); }
/* ARGSUSED */ static void child_handler(int sig) { int s = errno, status; if (signal(SIGCHLD, child_handler) == SIG_ERR) { close(trfd); } while (wait4(-1, &status, WNOHANG, NULL) > 0) ; errno = s; }
/* * process_reap - manage child demise and return exit status * * Args: pid -- id of process to reap * esp -- pointer to exist status * flags -- special reaping considerations * * Returns: * < 0 -- if there's a problem * 0 -- if no child to reap * > 0 -- process id of the child */ pid_t process_reap(pid_t pid, int *esp, int flags) { #ifdef _WINDOWS return 0; #else /* UNIX */ WAITSTATUS_T wstatus; pid_t rv; int wflags; #if HAVE_WAITPID wflags = 0; #ifdef WNOHANG if(flags & PR_NOHANG) wflags |= WNOHANG; #endif while (((rv = waitpid(pid, &wstatus, wflags)) < 0) && (errno != ECHILD)); #elif HAVE_WAIT4 wflags = 0; #ifdef WNOHANG if(flags & PR_NOHANG) wflags |= WNOHANG; #endif while (((rv = wait4(pid,&wstatus,wflags,NULL)) < 0) && (errno != ECHILD)); #elif HAVE_WAIT while (((rv = wait(&wstatus)) != pid) && ((rv > 0) || (errno != ECHILD))); #else /* BUG: BAIL */ #endif if(rv > 0) *esp = (WIFEXITED(wstatus)) ? (int) WEXITSTATUS(wstatus) : -1; return(rv); #endif /* UNIX */ }
bool Command_wait(struct Command *cmd, bool do_block) { int rc; if (cmd->rc!=-1) return true; switch (wait4(cmd->pid, &rc, (!do_block ? WNOHANG : 0), &cmd->rusage)) { case 0 : break; case -1 : cmd->err = errno; break; default : cmd->rc = rc; return true; } return false; }
static int sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage) { /* Prefer use waitpid to wait4 for non-blocking wait with WNOHANG option */ #ifdef HAVE_WAITPID /* Just doing getrusage(children) is not sufficient, because other * children may have exited previously. */ memset(rusage, 0, sizeof *rusage); return waitpid(pid, status, options); #elif HAVE_WAIT4 return wait4(pid, status, options, rusage); #else #error Please port this #endif }
static int syscall_filter (subprocess_t * p, int *status, struct rusage *usage) { int syscall_id; bool syscall_enter = true; int ret = RETURN_SUCCESS; while (true) { struct user_regs_struct regs; CHECK_ERROR ((ptrace (PTRACE_SYSCALL, p->pid, NULL, NULL) == -1), "ptrace failed"); CHECK_ERROR ((wait4 (p->pid, status, 0, usage) == -1), "wait failed"); if (WIFEXITED (*status) || WIFSIGNALED (*status) || WCOREDUMP (*status)) break; CHECK_ERROR ((ptrace (PTRACE_GETREGS, p->pid, NULL, ®s) == -1), "ptrace failed"); /* Getting syscall number is architecture dependant */ #if __WORDSIZE == 64 syscall_id = regs.orig_rax; #elif __WORDSIZE == 32 syscall_id = regs.orig_eax; #endif if (syscall_enter) { for (int i = 1; i <= p->limits->syscalls[0]; i++) if (syscall_id == p->limits->syscalls[i]) { p->status = DENIEDSYSCALL; rlimit_subprocess_kill (p); goto fail; } } syscall_enter ^= true; } if (false) fail: ret = RETURN_FAILURE; return ret; }
static int reap_children(struct repovec_t *repos) { int r = 0, running = 0; struct repo_t *repo; /* immediately reap zombies, but don't wait on still active children */ REPOVEC_FOREACH(repo, repos) { int stat_loc; if (repo->worker > 0) { if (wait4(repo->worker, &stat_loc, WNOHANG, NULL) == 0) { running++; } else { /* exited, grab the status */ r += WEXITSTATUS(stat_loc); } } }
static void trace_process(int pid, char **strtab) { int status; while (1) { wait4(pid, &status, WUNTRACED, NULL); if (get_stopsig(pid, strtab)) break; if (status == 0) break; if (get_syscall(pid, strtab)) break ; ptrace(PTRACE_SINGLESTEP, pid, NULL, 0); } }
void arch_reapChild(honggfuzz_t * hfuzz, fuzzer_t * fuzzer) { int status; for (;;) { #ifndef __WALL #define __WALL 0 #endif while (wait4(fuzzer->pid, &status, __WALL, NULL) != fuzzer->pid) ; LOG_D("Process (pid %d) came back with status %d", fuzzer->pid, status); if (arch_analyzeSignal(hfuzz, status, fuzzer)) { return; } } }
void debug_loop(int argc, char *argv[], void (*loop)(void)) { listen_port = atoi(argv[1]); argc-=2; argv++; argv++; int listen_fd = listen_sock(); struct sockaddr_in cli_addr; socklen_t cli_addr_len; if(argc >= 1 && !strcmp(argv[0], "-f")) { argc--; argv++; fprintf(stderr, "Start fork-pool\r\n"); while(1) { pid_t child; if((child = fork()) == 0) { int cli_sock = accept(listen_fd, (struct sockaddr *)&cli_addr, &cli_addr_len); in_fd = out_fd = cli_sock; // setsockopt(in_fd, SOL_SOCKET, SO_LINGER, &true_, sizeof(true_)); loop(); shutdown(cli_sock, SHUT_RDWR); _exit(0); } else { int stat_loc; struct rusage rusage; wait4(child, &stat_loc, 0, &rusage); if(WIFSIGNALED(stat_loc)) { fprintf(stderr, "Child process was signalled by %d\r\n", WTERMSIG(stat_loc)); } else if(WIFEXITED(stat_loc)) { if(WEXITSTATUS(stat_loc) != 0) fprintf(stderr, "Child process exited with code %d\r\n", WEXITSTATUS(stat_loc)); } else { fprintf(stderr, "Child process exited due to unknown reason\r\n"); } fprintf(stderr, "\r\n"); } } } else { int cli_sock = accept(listen_fd, (struct sockaddr *)&cli_addr, &cli_addr_len); in_fd = out_fd = cli_sock; loop(); _exit(0); } }
int main(int argc, const char *argv[]) { struct timespec timeout; pid_t cpid, pid; int fds[2], rfd, sig, status; if (pipe(fds) == -1) return (1); pid = fork(); switch (pid) { case -1: return (2); case 0: return (waiter_main(fds)); default: break; } if (close(fds[W]) == -1) return (3); rfd = fds[R]; if (read(rfd, &cpid, sizeof(cpid)) != sizeof(cpid)) return (4); if (close(rfd) == -1) return (5); timeout.tv_sec = 1; timeout.tv_nsec = 0; if (nanosleep(&timeout, NULL) == -1) return (6); sig = SIGKILL; if (kill(pid, sig) == -1) return (7); if (wait4(pid, &status, 0, NULL) == -1) return (8); if (!WIFSIGNALED(status)) return (9); if (WTERMSIG(status) != sig) return (10); if (kill(cpid, SIGKILL) == -1) return (11); return (0); }
static gboolean logd_term_action(int sig, gpointer userdata) { GList *log_iter = logd_client_list; GMainLoop *mainloop = (GMainLoop*)userdata; ha_logd_client_t *client = NULL; cl_log(LOG_DEBUG, "logd_term_action: received SIGTERM"); if (mainloop == NULL){ cl_log(LOG_ERR, "logd_term_action: invalid arguments"); return FALSE; } stop_reading = TRUE; while(log_iter != NULL) { client = log_iter->data; log_iter = log_iter->next; cl_log(LOG_DEBUG, "logd_term_action:" " waiting for %d messages to be read for process %s", (int)client->logchan->send_queue->current_qlen, client->app_name); client->logchan->ops->waitout(client->logchan); } cl_log(LOG_DEBUG, "logd_term_action" ": waiting for %d messages to be read by write process" , (int)chanspair[WRITE_PROC_CHAN]->send_queue->current_qlen); chanspair[WRITE_PROC_CHAN]->ops->waitout(chanspair[WRITE_PROC_CHAN]); cl_log(LOG_DEBUG, "logd_term_action: sending SIGTERM to write process"); if (CL_KILL(write_process_pid, SIGTERM) >= 0){ pid_t pid; pid = wait4(write_process_pid, NULL, 0, NULL); if (pid < 0){ cl_log(LOG_ERR, "wait4 for write process failed"); } } g_main_quit(mainloop); return TRUE; }
static void kill_job(child_process *cp, int reason) { int ret; struct rusage ru; /* brutal but efficient */ ret = kill(cp->pid, SIGKILL); if (ret < 0) { if (errno == ESRCH) { finish_job(cp, reason); return; } wlog("kill(%d, SIGKILL) failed: %s\n", cp->pid, strerror(errno)); } ret = wait4(cp->pid, &cp->ret, 0, &ru); finish_job(cp, reason); #ifdef PLAY_NICE_IN_kill_job int i, sig = SIGTERM; pid = cp->pid; for (i = 0; i < 2; i++) { /* check one last time if the job is done */ ret = check_completion(cp, WNOHANG); if (!ret || ret == -ECHILD) { /* check_completion ran finish_job() */ return; } /* not done, so signal it. SIGTERM first and check again */ errno = 0; ret = kill(pid, sig); if (ret < 0) { finish_job(cp, -errno); } sig = SIGKILL; check_completion(cp, WNOHANG); if (ret < 0) { finish_job(cp, errno); } usleep(50000); } #endif /* PLAY_NICE_IN_kill_job */ }