| 730 | } |
| 731 | |
| 732 | void start_process(Command* cmd, ProcessID id, uid_t uid, gid_t gid, int delay, sigset_t* mask) { |
| 733 | if (!cmd->argv) |
| 734 | return; |
| 735 | |
| 736 | pid_t pid = fork(); |
| 737 | |
| 738 | if (pid < 0) { /* fork error */ |
| 739 | cmd->last_start = timer(); |
| 740 | int fork_delay = cmd->get_and_update_current_restart_delay(); |
| 741 | cmd->fork_retry_time = cmd->last_start + fork_delay; |
| 742 | log_err("fork", |
| 743 | errno, |
| 744 | "Unable to fork new %s process, restarting %s in %d seconds", |
| 745 | cmd->argv[0], |
| 746 | cmd->ssection.c_str(), |
| 747 | fork_delay); |
| 748 | return; |
| 749 | } else if (pid == 0) { /* we are the child */ |
| 750 | /* remove signal handlers from parent */ |
| 751 | signal(SIGHUP, SIG_DFL); |
| 752 | signal(SIGINT, SIG_DFL); |
| 753 | signal(SIGTERM, SIG_DFL); |
| 754 | |
| 755 | /* All output in this block should be to stdout (for SevInfo messages) or stderr (for SevError messages) */ |
| 756 | /* Using log_msg() or log_err() from the child will cause the logs to be written incorrectly */ |
| 757 | dup2(cmd->pipes[0][1], fileno(stdout)); |
| 758 | dup2(cmd->pipes[1][1], fileno(stderr)); |
| 759 | |
| 760 | if (cmd->delete_envvars != nullptr && std::strlen(cmd->delete_envvars) > 0) { |
| 761 | std::string vars(cmd->delete_envvars); |
| 762 | size_t start = 0; |
| 763 | do { |
| 764 | size_t bound = vars.find(" ", start); |
| 765 | std::string var = vars.substr(start, bound - start); |
| 766 | fprintf(stdout, "Deleting parent environment variable: \'%s\'\n", var.c_str()); |
| 767 | fflush(stdout); |
| 768 | if (unsetenv(var.c_str())) { |
| 769 | fprintf(stderr, |
| 770 | "Unable to remove parent environment variable: %s (unsetenv error %d: %s)\n", |
| 771 | var.c_str(), |
| 772 | errno, |
| 773 | strerror(errno)); |
| 774 | exit(1); |
| 775 | } |
| 776 | start = bound; |
| 777 | while (vars[start] == ' ') |
| 778 | start++; |
| 779 | } while (start <= vars.length()); |
| 780 | } |
| 781 | |
| 782 | #ifdef __linux__ |
| 783 | signal(SIGCHLD, SIG_DFL); |
| 784 | |
| 785 | sigprocmask(SIG_SETMASK, mask, nullptr); |
| 786 | |
| 787 | /* death of our parent raises SIGHUP */ |
| 788 | prctl(PR_SET_PDEATHSIG, SIGHUP); |
| 789 | if (getppid() == 1) /* parent already died before prctl */ |