| 1708 | #endif |
| 1709 | |
| 1710 | static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, |
| 1711 | kwsysProcessCreateInformation* si) |
| 1712 | { |
| 1713 | sigset_t mask; |
| 1714 | sigset_t old_mask; |
| 1715 | int pgidPipe[2]; |
| 1716 | char tmp; |
| 1717 | ssize_t readRes; |
| 1718 | |
| 1719 | /* Create the error reporting pipe. */ |
| 1720 | if (pipe(si->ErrorPipe) < 0) { |
| 1721 | return 0; |
| 1722 | } |
| 1723 | |
| 1724 | /* Create a pipe for detecting that the child process has created a process |
| 1725 | group and session. */ |
| 1726 | if (pipe(pgidPipe) < 0) { |
| 1727 | kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); |
| 1728 | kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); |
| 1729 | return 0; |
| 1730 | } |
| 1731 | |
| 1732 | /* Set close-on-exec flag on the pipe's write end. */ |
| 1733 | if (fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 || |
| 1734 | fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0) { |
| 1735 | kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); |
| 1736 | kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); |
| 1737 | kwsysProcessCleanupDescriptor(&pgidPipe[0]); |
| 1738 | kwsysProcessCleanupDescriptor(&pgidPipe[1]); |
| 1739 | return 0; |
| 1740 | } |
| 1741 | |
| 1742 | /* Block SIGINT / SIGTERM while we start. The purpose is so that our signal |
| 1743 | handler doesn't get called from the child process after the fork and |
| 1744 | before the exec, and subsequently start kill()'ing PIDs from ForkPIDs. */ |
| 1745 | sigemptyset(&mask); |
| 1746 | sigaddset(&mask, SIGINT); |
| 1747 | sigaddset(&mask, SIGTERM); |
| 1748 | if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) { |
| 1749 | kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); |
| 1750 | kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); |
| 1751 | kwsysProcessCleanupDescriptor(&pgidPipe[0]); |
| 1752 | kwsysProcessCleanupDescriptor(&pgidPipe[1]); |
| 1753 | return 0; |
| 1754 | } |
| 1755 | |
| 1756 | /* Fork off a child process. */ |
| 1757 | #if defined(__VMS) |
| 1758 | /* VMS needs vfork and execvp to be in the same function because |
| 1759 | they use setjmp/longjmp to run the child startup code in the |
| 1760 | parent! TODO: OptionDetach. Also |
| 1761 | TODO: CreateProcessGroup. */ |
| 1762 | cp->ForkPIDs[prIndex] = vfork(); |
| 1763 | #else |
| 1764 | cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si); |
| 1765 | #endif |
| 1766 | if (cp->ForkPIDs[prIndex] < 0) { |
| 1767 | sigprocmask(SIG_SETMASK, &old_mask, 0); |
no test coverage detected
searching dependent graphs…