void do_fork_exec(char *cmdline, int *pid, int *stdin_fd, int *stdout_fd, int *stderr_fd) { int inpipe[2], outpipe[2], errpipe[2]; if (pipe(inpipe) || pipe(outpipe) || (stderr_fd && pipe(errpipe))) { perror("pipe"); exit(1); } switch (*pid = fork()) { case -1: perror("fork"); exit(-1); case 0: if (stderr_fd) { fix_fds(inpipe[0], outpipe[1], errpipe[1]); } else fix_fds(inpipe[0], outpipe[1], 2); do_exec(cmdline); exit(-1); default:; } close(inpipe[0]); close(outpipe[1]); *stdin_fd = inpipe[1]; *stdout_fd = outpipe[0]; if (stderr_fd) { close(errpipe[1]); *stderr_fd = errpipe[0]; } }
void do_fork_exec(const char *cmdline, int *pid, int *stdin_fd, int *stdout_fd, int *stderr_fd) { int inpipe[2], outpipe[2], errpipe[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, inpipe) || socketpair(AF_UNIX, SOCK_STREAM, 0, outpipe) || (stderr_fd && socketpair(AF_UNIX, SOCK_STREAM, 0, errpipe))) { perror("socketpair"); exit(1); } switch (*pid = fork()) { case -1: perror("fork"); exit(-1); case 0: if (stderr_fd) { fix_fds(inpipe[0], outpipe[1], errpipe[1]); } else fix_fds(inpipe[0], outpipe[1], 2); if (exec_func != NULL) exec_func(cmdline); exit(-1); default:; } close(inpipe[0]); close(outpipe[1]); *stdin_fd = inpipe[1]; *stdout_fd = outpipe[0]; if (stderr_fd) { close(errpipe[1]); *stderr_fd = errpipe[0]; } }
bool daemonize(void) { pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { return false; } /* If we got a good PID, then we are the parent and can exit */ if (pid > 0) { exit(EXIT_SUCCESS); } /* now in forked child */ /* Fork again, to become a real daemon */ pid = fork(); if (pid < 0) { exit(1); } else if (pid > 0) { exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* we should log something here... */ return false; } /* Change the current working directory */ (void)chdir("/"); /* ignore errors */ /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO), close(STDERR_FILENO); /* Replace standard file descriptors with /dev/null */ fix_fds(); return true; }
int execute(const char *file, char * const*args) { if(strcmp(file, "exit") == 0) { kill(getpid(), SIGINT); exit(0); } pid_t childProc = fork(); int saved_stdout = dup(STDOUT_FILENO); int saved_stdin = dup(STDIN_FILENO); if(childProc >= 0) { if(childProc == 0) { if(!fix_fds()) { exit(0); } execvp(file, args); fprintf(stderr, "Error: %s\n", strerror(errno)); exit(0); } else { if(!background) { children[nchildren++] = childProc; } int status; if(!background) { waitpid(childProc, &status, 0); nchildren--; } else { int pid; while((pid=waitpid(-1, &status, WNOHANG)) > 0) { printf("PID %d exited.\n", pid); } } restore_fds(saved_stdin, saved_stdout); return status; } } else { fprintf(stderr, "Error: %s\n", strerror(errno)); } return -1; }
void run_cmd(char * const *args, int *cmds, int numcmds) { int s_stdin = dup(STDIN_FILENO); int s_stdout = dup(STDOUT_FILENO); if(numcmds <= 0) { return; } int fds[2*(numcmds-1)]; for(int i=0; i<numcmds-1; i++) { if(pipe(fds + i*2) < 0) { fprintf(stderr, "Pipe error on line %d", __LINE__); perror(""); restore_fds(s_stdin, s_stdout); return; } } int childpid; for(int i=0; i<numcmds; i++) { int index = cmds[i]; childpid = fork(); if(childpid == 0) { if(!fix_fds()) { return; } // child proc //fprintf(stderr, "%d\n", i); if(i < numcmds-1) { //fprintf(stderr, "Duping stdout for cmd %s\n", *(args + index)); if(dup2(fds[i*2 + 1], 1) < 0) { fprintf(stderr, "Dup2 error on line %d", __LINE__); perror(""); // restore_fds(s_stdin, s_stdout); exit(0); } } if(i > 0) { //fprintf(stderr, "Duping stdin for cmd %s\n", *(args + index)); if(dup2(fds[i*2-2], 0) < 0) { fprintf(stderr, "Dup2 error on line %d\n", __LINE__); fprintf(stderr, "File descriptor: %d", fds[i*2-2]); perror(""); // restore_fds(s_stdin, s_stdout); // exit(0); kill(getppid(), SIGINT); exit(0); } } for(int j=0; j<numcmds*2-2; j++) { close(fds[j]); } //fprintf(stderr, "Exec cmd %s\n", *(args + index)); execvp(*(args + index), args + index); exit(0); } else if(childpid < 0) { fprintf(stderr, "Fork Error on line %d", __LINE__); perror(""); // restore_fds(s_stdin, s_stdout); exit(0); } else if(!background) { children[nchildren++] = childpid; } } for(int i=0; i<2*(numcmds-1); i++) { close(fds[i]); } int status; if(!background) { for(int i=0; i<numcmds; i++) { wait(&status); nchildren--; } } else { int pid; while((pid=waitpid(-1, &status, WNOHANG)) > 0) { fprintf(stderr, "PID %d exited.\n", pid); } } restore_fds(s_stdin, s_stdout); }