| 1878 | |
| 1879 | |
| 1880 | inline void Child::execute_child() { |
| 1881 | #ifndef __USING_WINDOWS__ |
| 1882 | int sys_ret = -1; |
| 1883 | auto& stream = parent_->stream_; |
| 1884 | |
| 1885 | try { |
| 1886 | if (stream.write_to_parent_ == 0) |
| 1887 | stream.write_to_parent_ = dup(stream.write_to_parent_); |
| 1888 | |
| 1889 | if (stream.err_write_ == 0 || stream.err_write_ == 1) |
| 1890 | stream.err_write_ = dup(stream.err_write_); |
| 1891 | |
| 1892 | // Make the child owned descriptors as the |
| 1893 | // stdin, stdout and stderr for the child process |
| 1894 | auto _dup2_ = [](int fd, int to_fd) { |
| 1895 | if (fd == to_fd) { |
| 1896 | // dup2 syscall does not reset the |
| 1897 | // CLOEXEC flag if the descriptors |
| 1898 | // provided to it are same. |
| 1899 | // But, we need to reset the CLOEXEC |
| 1900 | // flag as the provided descriptors |
| 1901 | // are now going to be the standard |
| 1902 | // input, output and error |
| 1903 | util::set_clo_on_exec(fd, false); |
| 1904 | } else if(fd != -1) { |
| 1905 | int res = dup2(fd, to_fd); |
| 1906 | if (res == -1) throw OSError("dup2 failed", errno); |
| 1907 | } |
| 1908 | }; |
| 1909 | |
| 1910 | // Create the standard streams |
| 1911 | _dup2_(stream.read_from_parent_, 0); // Input stream |
| 1912 | _dup2_(stream.write_to_parent_, 1); // Output stream |
| 1913 | _dup2_(stream.err_write_, 2); // Error stream |
| 1914 | |
| 1915 | // Close the duped descriptors |
| 1916 | if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2) |
| 1917 | subprocess_close(stream.read_from_parent_); |
| 1918 | |
| 1919 | if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2) |
| 1920 | subprocess_close(stream.write_to_parent_); |
| 1921 | |
| 1922 | if (stream.err_write_ != -1 && stream.err_write_ > 2) |
| 1923 | subprocess_close(stream.err_write_); |
| 1924 | |
| 1925 | // Close all the inherited fd's except the error write pipe |
| 1926 | if (parent_->close_fds_) { |
| 1927 | int max_fd = sysconf(_SC_OPEN_MAX); |
| 1928 | if (max_fd == -1) throw OSError("sysconf failed", errno); |
| 1929 | |
| 1930 | for (int i = 3; i < max_fd; i++) { |
| 1931 | if (i == err_wr_pipe_) continue; |
| 1932 | subprocess_close(i); |
| 1933 | } |
| 1934 | } |
| 1935 | |
| 1936 | // Change the working directory if provided |
| 1937 | if (parent_->cwd_.length()) { |
no test coverage detected