@@ -5,8 +5,27 @@ export module rstd:process.command;
55export import :process.exit_status;
66export import :io;
77export import :path;
8+ export import :os.fd;
89export import rstd.alloc;
910import :sys.io.stdio;
11+ #if RSTD_OS_LINUX
12+ export import :os.linux.pidfd;
13+ #endif
14+
15+ #if RSTD_OS_UNIX
16+ export namespace rstd ::os::unix::process
17+ {
18+ struct CommandExt ;
19+ struct ChildExt ;
20+ } // namespace rstd::os::unix::process
21+ #endif
22+ #if RSTD_OS_LINUX
23+ export namespace rstd ::os::linux::process
24+ {
25+ struct CommandExt ;
26+ struct ChildExt ;
27+ } // namespace rstd::os::linux::process
28+ #endif
1029
1130using ::alloc::ffi::CString;
1231using ::alloc::string::String;
@@ -39,6 +58,12 @@ struct ChildStdin {
3958 ChildStdin& operator =(ChildStdin&&) = delete ;
4059 ChildStdin () = default ;
4160 explicit ChildStdin (int f): fd(f) {}
61+ #if RSTD_OS_UNIX
62+ auto as_raw_fd () const noexcept -> os::fd::RawFd { return fd; }
63+ auto as_fd () const noexcept [[clang::lifetimebound]] -> os::fd::BorrowedFd {
64+ return os::fd::BorrowedFd::borrow_raw (fd);
65+ }
66+ #endif
4267};
4368
4469// / A handle to a child process's standard output (read end of pipe).
@@ -49,6 +74,12 @@ struct ChildStdout {
4974 ChildStdout& operator =(ChildStdout&&) = delete ;
5075 ChildStdout () = default ;
5176 explicit ChildStdout (int f): fd(f) {}
77+ #if RSTD_OS_UNIX
78+ auto as_raw_fd () const noexcept -> os::fd::RawFd { return fd; }
79+ auto as_fd () const noexcept [[clang::lifetimebound]] -> os::fd::BorrowedFd {
80+ return os::fd::BorrowedFd::borrow_raw (fd);
81+ }
82+ #endif
5283};
5384
5485// / A handle to a child process's standard error (read end of pipe).
@@ -59,6 +90,12 @@ struct ChildStderr {
5990 ChildStderr& operator =(ChildStderr&&) = delete ;
6091 ChildStderr () = default ;
6192 explicit ChildStderr (int f): fd(f) {}
93+ #if RSTD_OS_UNIX
94+ auto as_raw_fd () const noexcept -> os::fd::RawFd { return fd; }
95+ auto as_fd () const noexcept [[clang::lifetimebound]] -> os::fd::BorrowedFd {
96+ return os::fd::BorrowedFd::borrow_raw (fd);
97+ }
98+ #endif
6299};
63100
64101} // namespace rstd::process
@@ -106,6 +143,20 @@ export namespace rstd::process
106143
107144// / A child process handle.
108145struct Child {
146+ private:
147+ friend sys::process_impl::Spawn;
148+ #if RSTD_OS_UNIX
149+ friend os::unix::process::ChildExt;
150+ #endif
151+ #if RSTD_OS_LINUX
152+ friend os::linux::process::ChildExt;
153+ Option<os::linux::process::PidFd> pidfd_;
154+ #endif
155+ #if RSTD_OS_UNIX
156+ auto send_signal (i32 signal, bool group) const -> io::Result<empty>;
157+ #endif
158+
159+ public:
109160 int pid { -1 };
110161#if RSTD_OS_WINDOWS
111162 void * process_handle { nullptr };
@@ -143,7 +194,11 @@ struct Child {
143194
144195 ~Child ();
145196 Child (Child&& o) noexcept
146- : pid(o.pid),
197+ :
198+ #if RSTD_OS_LINUX
199+ pidfd_ (o.pidfd_.take()),
200+ #endif
201+ pid (o.pid),
147202#if RSTD_OS_WINDOWS
148203 process_handle (o.process_handle),
149204#endif
@@ -171,6 +226,14 @@ class Command {
171226 Stdio cfg_stdout_ { Stdio::inherit () };
172227 Stdio cfg_stderr_ { Stdio::inherit () };
173228 bool env_clear_ { false };
229+ #if RSTD_OS_UNIX
230+ Option<i32 > process_group_;
231+ friend os::unix::process::CommandExt;
232+ #endif
233+ #if RSTD_OS_LINUX
234+ bool create_pidfd_ { false };
235+ friend os::linux::process::CommandExt;
236+ #endif
174237
175238 friend sys::process_impl::Spawn;
176239
0 commit comments