diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake index 28e4cda5e..7e28dae44 100644 --- a/cmake/ConfigureChecks.cmake +++ b/cmake/ConfigureChecks.cmake @@ -107,6 +107,7 @@ check_include_file_cxx(sys/select.h HAVE_SYS_SELECT_H) check_include_files("sys/types.h;sys/sysctl.h" HAVE_SYS_SYSCTL_H) check_include_file_cxx(termios.h HAVE_TERMIOS_H) # Needed for TIOCGWINSZ +check_cxx_symbol_exists(pipe2 unistd.h HAVE_PIPE2) check_cxx_symbol_exists(wcscasecmp wchar.h HAVE_WCSCASECMP) check_cxx_symbol_exists(wcsdup wchar.h HAVE_WCSDUP) check_cxx_symbol_exists(wcslcpy wchar.h HAVE_WCSLCPY) diff --git a/config_cmake.h.in b/config_cmake.h.in index 4dbf7520e..5266f6eb0 100644 --- a/config_cmake.h.in +++ b/config_cmake.h.in @@ -58,6 +58,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NCURSES_TERM_H 1 +/* Define to 1 if you have the 'pipe2' function. */ +#cmakedefine HAVE_PIPE2 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SIGINFO_H 1 diff --git a/src/fds.cpp b/src/fds.cpp index f71c282ed..545e6f9ea 100644 --- a/src/fds.cpp +++ b/src/fds.cpp @@ -74,21 +74,30 @@ static autoclose_fd_t heightenize_fd(autoclose_fd_t fd, bool input_has_cloexec) maybe_t make_autoclose_pipes() { int pipes[2] = {-1, -1}; - // TODO: use pipe2 here if available. + bool already_cloexec = false; +#ifdef HAVE_PIPE2 + if (pipe2(pipes, O_CLOEXEC) < 0) { + FLOGF(warning, PIPE_ERROR); + wperror(L"pipe2"); + return none(); + } + already_cloexec = true; +#else if (pipe(pipes) < 0) { FLOGF(warning, PIPE_ERROR); wperror(L"pipe"); return none(); } +#endif autoclose_fd_t read_end{pipes[0]}; autoclose_fd_t write_end{pipes[1]}; // Ensure our fds are out of the user range. - read_end = heightenize_fd(std::move(read_end), false); + read_end = heightenize_fd(std::move(read_end), already_cloexec); if (!read_end.valid()) return none(); - write_end = heightenize_fd(std::move(write_end), false); + write_end = heightenize_fd(std::move(write_end), already_cloexec); if (!write_end.valid()) return none(); return autoclose_pipes_t(std::move(read_end), std::move(write_end));