diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-09-02 22:29:11 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-09-03 01:52:38 +0800 |
commit | 545a638929218a83d194402b3d52f5bffd87d9eb (patch) | |
tree | f659f671fec17f3ef7dced31f3a1f59673d18690 /src/base/platform/unix/PosixSpawnSubProcess.cpp | |
parent | 5035f18f44f675af2faa4019b6de14b3f3aab270 (diff) | |
download | cru-545a638929218a83d194402b3d52f5bffd87d9eb.tar.gz cru-545a638929218a83d194402b3d52f5bffd87d9eb.tar.bz2 cru-545a638929218a83d194402b3d52f5bffd87d9eb.zip |
UnixFileDescriptor.
Diffstat (limited to 'src/base/platform/unix/PosixSpawnSubProcess.cpp')
-rw-r--r-- | src/base/platform/unix/PosixSpawnSubProcess.cpp | 119 |
1 files changed, 49 insertions, 70 deletions
diff --git a/src/base/platform/unix/PosixSpawnSubProcess.cpp b/src/base/platform/unix/PosixSpawnSubProcess.cpp index 631c14b8..25e6c38c 100644 --- a/src/base/platform/unix/PosixSpawnSubProcess.cpp +++ b/src/base/platform/unix/PosixSpawnSubProcess.cpp @@ -14,24 +14,7 @@ #include <unordered_map> namespace cru::platform::unix { -PosixSpawnSubProcessImpl::PosixSpawnSubProcessImpl() - : pid_(0), - exit_code_(0), - stdin_pipe_(UnixPipe::Usage::Send, false), - stdout_pipe_(UnixPipe::Usage::Receive, false), - stderr_pipe_(UnixPipe::Usage::Receive, false) { - stdin_stream_ = std::make_unique<UnixFileStream>( - stdin_pipe_.GetSelfFileDescriptor(), false, false, true, true); - stdout_stream_ = std::make_unique<UnixFileStream>( - stdout_pipe_.GetSelfFileDescriptor(), false, true, false, true); - stderr_stream_ = std::make_unique<UnixFileStream>( - stderr_pipe_.GetSelfFileDescriptor(), false, true, false, true); - - stdout_buffer_stream_ = - std::make_unique<io::AutoReadStream>(stdout_stream_.get(), true, false); - stderr_buffer_stream_ = - std::make_unique<io::AutoReadStream>(stderr_stream_.get(), true, false); -} +PosixSpawnSubProcessImpl::PosixSpawnSubProcessImpl() : pid_(0), exit_code_(0) {} PosixSpawnSubProcessImpl::~PosixSpawnSubProcessImpl() {} @@ -71,8 +54,7 @@ void DestroyCstrArray(char** argv) { void PosixSpawnSubProcessImpl::PlatformCreateProcess( const SubProcessStartInfo& start_info) { - int error; - auto check_error = [&error](String message) { + auto check_error = [](int error, String message) { if (error == 0) return; std::unique_ptr<ErrnoException> inner(new ErrnoException({}, error)); throw SubProcessFailedToStartException(std::move(message), @@ -80,54 +62,45 @@ void PosixSpawnSubProcessImpl::PlatformCreateProcess( }; posix_spawn_file_actions_t file_actions; - error = posix_spawn_file_actions_init(&file_actions); - check_error(u"Failed to call posix_spawn_file_actions_init."); + check_error(posix_spawn_file_actions_init(&file_actions), + u"Failed to call posix_spawn_file_actions_init."); Guard file_actions_guard( [&file_actions] { posix_spawn_file_actions_destroy(&file_actions); }); - // dup2 stdin/stdout/stderr - error = posix_spawn_file_actions_adddup2( - &file_actions, stdin_pipe_.GetOtherFileDescriptor(), STDIN_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdin."); - error = posix_spawn_file_actions_adddup2( - &file_actions, stdout_pipe_.GetOtherFileDescriptor(), STDOUT_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdout."); - error = posix_spawn_file_actions_adddup2( - &file_actions, stderr_pipe_.GetOtherFileDescriptor(), STDERR_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stderr."); - - error = posix_spawn_file_actions_addclose( - &file_actions, stdin_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd of stdin."); - error = posix_spawn_file_actions_addclose( - &file_actions, stdout_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd stdout."); - error = posix_spawn_file_actions_addclose( - &file_actions, stderr_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd stderr."); + auto add_dup2 = [&check_error, &file_actions](int from, int to, + StringView name) { + check_error( + posix_spawn_file_actions_adddup2(&file_actions, from, to), + Format(u"Failed to call posix_spawn_file_actions_adddup2 on {}.", + name)); + }; - error = posix_spawn_file_actions_addclose( - &file_actions, stdin_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stdin."); - error = posix_spawn_file_actions_addclose( - &file_actions, stdout_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stdout."); - error = posix_spawn_file_actions_addclose( - &file_actions, stderr_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stderr."); + auto add_close = [&check_error, &file_actions]( + UniDirectionalUnixPipeResult& pipe, StringView name) { + check_error(posix_spawn_file_actions_addclose(&file_actions, pipe.read), + Format(u"Failed to call posix_spawn_file_actions_addclose on " + u"read end of pipe {}.", + name)); + check_error(posix_spawn_file_actions_addclose(&file_actions, pipe.write), + Format(u"Failed to call posix_spawn_file_actions_addclose on " + u"write end of pipe {}.", + name)); + }; + + auto my_stdin = OpenUniDirectionalPipe(); + auto my_stdout = OpenUniDirectionalPipe(); + auto my_stderr = OpenUniDirectionalPipe(); + + add_dup2(my_stdin.read, STDIN_FILENO, u"stdin"); + add_dup2(my_stdout.write, STDOUT_FILENO, u"stdout"); + add_dup2(my_stderr.write, STDERR_FILENO, u"stderr"); + add_close(my_stdin, u"stdin"); + add_close(my_stdout, u"stdout"); + add_close(my_stderr, u"stderr"); posix_spawnattr_t attr; - error = posix_spawnattr_init(&attr); - check_error(u"Failed to call posix_spawnattr_init."); + check_error(posix_spawnattr_init(&attr), + u"Failed to call posix_spawnattr_init."); Guard attr_guard([&attr] { posix_spawnattr_destroy(&attr); }); #ifdef CRU_PLATFORM_OSX @@ -146,15 +119,21 @@ void PosixSpawnSubProcessImpl::PlatformCreateProcess( auto envp = CreateCstrArray(start_info.environments); Guard envp_guard([envp] { DestroyCstrArray(envp); }); - error = posix_spawnp(&pid_, exe.c_str(), &file_actions, &attr, argv, envp); - check_error(u"Failed to call posix_spawnp."); + check_error( + posix_spawnp(&pid_, exe.c_str(), &file_actions, &attr, argv, envp), + u"Failed to call posix_spawnp."); - error = ::close(stdin_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stdin."); - error = ::close(stdout_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stdout."); - error = ::close(stderr_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stderr."); + stdin_stream_ = std::make_unique<UnixFileStream>(std::move(my_stdin.write), + false, false, true); + stdout_stream_ = std::make_unique<UnixFileStream>(std::move(my_stdout.read), + false, true, false); + stderr_stream_ = std::make_unique<UnixFileStream>(std::move(my_stderr.read), + false, true, false); + + stdout_buffer_stream_ = + std::make_unique<io::AutoReadStream>(stdout_stream_.get(), true, false); + stderr_buffer_stream_ = + std::make_unique<io::AutoReadStream>(stderr_stream_.get(), true, false); } SubProcessExitResult PosixSpawnSubProcessImpl::PlatformWaitForProcess() { |