Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/fast_io_hosted/process/process/option.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ enum class process_mode : ::std::uint_least64_t
// [POSIX] Using vfork to create processes, but this prevents many parameters from taking effect (vfork does not allow modification of global memory before exec).
follow = static_cast<::std::uint_least64_t>(1) << 4,
// [POSIX, WINDOWS, WINNT] Allow symbolic links to follow
detach = static_cast<::std::uint_least64_t>(1) << 5,
// [POSIX] Detach after process created. Always success even if the process fails to launch. This flag disable pipes used to collect status from subprocess. Takes no effect if posix_vfork is set
};

inline constexpr process_mode operator&(process_mode x, process_mode y) noexcept
Expand Down
58 changes: 57 additions & 1 deletion include/fast_io_hosted/process/process/posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,55 @@ struct io_redirector
}
};

inline pid_t detach_fork_execveat_common_impl(int dirfd, char const *cstr, char const *const *args, char const *const *envp, posix_process_io const &pio, process_mode mode)
{
pid_t pid = posix_fork();
if (pid == 0)
{
// subprocess
if ((mode & process_mode::new_session) == process_mode::new_session)
{
posix_setsid();
}

int t_errno{};
// io redirection
{
io_redirector r;
auto rc = r.redirect_all(pio);
if (rc.error)
{
t_errno = rc.code;
}
}

if (t_errno == 0)
{
posix_execveat(dirfd, cstr, args, envp, mode);
}
// execve only return on error, so t_errno always contains an error code
// special exit code 127 indicates error of exec
#if defined(__linux__)
#ifdef __NR_exit_group
::fast_io::system_call_no_return<__NR_exit_group>(127);
#else
::fast_io::system_call_no_return<__NR_exit>(127);
#endif
#else
::fast_io::posix::libc_exit(127);
#endif
}
// parent process
// currently parent process never close pipes
// uncomment those lines to enable automatically closing pipe ends
#if 0
io_redirector::close_pipe_ends(0, pio.in);
io_redirector::close_pipe_ends(1, pio.out);
io_redirector::close_pipe_ends(2, pio.err);
#endif
return pid;
}

inline pid_t pipefork_execveat_common_impl(int dirfd, char const *cstr, char const *const *args, char const *const *envp, posix_process_io const &pio, process_mode mode)
{
posix_pipe error_pipe;
Expand Down Expand Up @@ -611,7 +660,14 @@ inline pid_t pipefork_execveat_common_impl(int dirfd, char const *cstr, char con
template <typename path_type>
inline pid_t pipefork_execveat_impl(int dirfd, path_type const &csv, char const *const *args, char const *const *envp, posix_process_io const &pio, process_mode mode)
{
return ::fast_io::posix_api_common(csv, [&](char const *cstr) { return pipefork_execveat_common_impl(dirfd, cstr, args, envp, pio, mode); });
if ((mode & process_mode::detach) == process_mode::detach)
{
return ::fast_io::posix_api_common(csv, [&](char const *cstr) { return detach_fork_execveat_common_impl(dirfd, cstr, args, envp, pio, mode); });
}
else
{
return ::fast_io::posix_api_common(csv, [&](char const *cstr) { return pipefork_execveat_common_impl(dirfd, cstr, args, envp, pio, mode); });
}
}

template <typename path_type>
Expand Down