dius 0.1.0
Loading...
Searching...
No Matches
process.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/assert/prelude.h"
4#include "di/container/path/path.h"
5#include "di/container/string/prelude.h"
6#include "di/container/tree/tree_map.h"
7#include "di/container/vector/prelude.h"
8#include "di/util/prelude.h"
9#include "dius/error.h"
10#include "dius/platform_process.h"
11#include "dius/sync_file.h"
12#include "dius/tty.h"
13
14namespace dius::system {
16public:
17 explicit ProcessResult(int exit_code_or_signal, bool signaled)
18 : m_exit_code_or_signal(exit_code_or_signal), m_signaled(signaled) {}
19
20 auto signaled() const -> bool { return m_signaled; }
21 auto exited() const -> bool { return !m_signaled; }
22
23 auto exit_code() const -> int {
24 ASSERT(exited());
25 return m_exit_code_or_signal;
26 }
27
28 auto signal() const -> int {
29 ASSERT(signaled());
30 return m_exit_code_or_signal;
31 }
32
33private:
34 int m_exit_code_or_signal { 0 };
35 bool m_signaled { false };
36};
37
39public:
40 static auto self() -> ProcessHandle;
41
42 ProcessHandle() = default;
43 constexpr explicit ProcessHandle(ProcessId id) : m_id(id) {}
44
45 constexpr auto id() const -> ProcessId { return m_id; }
46
47 auto wait() -> di::Result<ProcessResult>;
48
49 auto signal(Signal signal) -> di::Result<>;
50
51private:
52 ProcessId m_id { -1 };
53};
54
55class Process {
56 struct FileAction {
57 enum class Type {
58 Open,
59 Dup,
60 Close,
61 };
62
63 Type type { Type::Dup };
64 i32 arg0 = 0;
65 i32 arg1 = 0;
66 i32 arg2 = 0;
67 di::Path path;
68 };
69
70public:
71 explicit Process(di::Vector<di::TransparentString> arguments) : m_arguments(di::move(arguments)) {}
72
73 auto with_file_open(i32 fd, di::Path path, OpenMode open_mode, u16 create_mode = 0666) && -> Process {
74 m_file_actions.push_back(
75 { FileAction::Type::Open, fd, static_cast<i32>(open_mode), i32(create_mode), di::move(path) });
76 return di::move(*this);
77 }
78
79 auto with_file_close(i32 fd) && -> Process {
80 m_file_actions.push_back({ FileAction::Type::Close, fd, 0, 0, {} });
81 return di::move(*this);
82 }
83
84 auto with_file_dup(i32 old_fd, i32 new_fd) && -> Process {
85 m_file_actions.push_back({ FileAction::Type::Dup, old_fd, new_fd, 0, {} });
86 return di::move(*this);
87 }
88
89 auto with_tty_window_size(int fd, tty::WindowSize const& size) && -> Process {
90 m_tty_window_size = { fd, size };
91 return di::move(*this).use_fork();
92 }
93
94 auto with_controlling_tty(int fd) && -> Process {
95 m_controlling_tty = fd;
96 return di::move(*this).use_fork();
97 }
98
100 m_new_session = true;
101 return di::move(*this);
102 }
103
104 auto with_env(di::TransparentString key, di::TransparentString value) && -> Process {
105 m_extra_env_vars.insert_or_assign(di::move(key), di::move(value));
106 return di::move(*this);
107 }
108
114 m_current_working_directory = di::move(path);
115 m_require_current_working_directory = false;
116 return di::move(*this);
117 }
118
120 auto with_current_working_directory(di::Path path) && -> Process {
121 m_current_working_directory = di::move(path);
122 m_require_current_working_directory = true;
123 return di::move(*this);
124 }
125
126 auto use_fork(bool b = true) && -> Process {
127 m_use_fork = b;
128 return di::move(*this);
129 }
130
131 auto spawn() && -> di::Result<ProcessHandle>;
132
133 auto spawn_and_wait() && -> di::Result<ProcessResult> {
134 auto handle = TRY(di::move(*this).spawn());
135 return handle.wait();
136 }
137
138private:
139 auto spawn_with_fork() && -> di::Result<ProcessHandle>;
140 auto spawn_with_posix_spawn() && -> di::Result<ProcessHandle>;
141
142 di::Vector<di::TransparentString> m_arguments;
143 di::Vector<FileAction> m_file_actions;
144 di::Optional<di::Path> m_current_working_directory;
145 bool m_require_current_working_directory { false };
146 di::TreeMap<di::TransparentString, di::TransparentString> m_extra_env_vars;
147 di::Optional<di::Tuple<i32, tty::WindowSize>> m_tty_window_size;
148 di::Optional<i32> m_controlling_tty;
149 bool m_new_session { false };
150 bool m_use_fork { false };
151};
152
154auto mask_signal(Signal signal) -> di::Result<void>;
155auto wait_for_signal(Signal signal) -> di::Result<Signal>;
156
158auto get_program_name() -> di::PathView;
159
161auto get_environment() -> di::TreeMap<di::TransparentString, di::TransparentString> const&;
162
164auto get_hostname() -> di::Result<di::TransparentString>;
165
169[[noreturn]] void exit_thread();
170
171[[noreturn]] void exit_process(int status_code);
172}
auto wait() -> di::Result< ProcessResult >
constexpr ProcessHandle(ProcessId id)
Definition process.h:43
static auto self() -> ProcessHandle
auto signal(Signal signal) -> di::Result<>
constexpr auto id() const -> ProcessId
Definition process.h:45
auto signaled() const -> bool
Definition process.h:20
ProcessResult(int exit_code_or_signal, bool signaled)
Definition process.h:17
auto exited() const -> bool
Definition process.h:21
auto exit_code() const -> int
Definition process.h:23
auto signal() const -> int
Definition process.h:28
auto with_file_dup(i32 old_fd, i32 new_fd) &&-> Process
Definition process.h:84
auto use_fork(bool b=true) &&-> Process
Definition process.h:126
auto with_env(di::TransparentString key, di::TransparentString value) &&-> Process
Definition process.h:104
auto with_file_close(i32 fd) &&-> Process
Definition process.h:79
auto spawn() &&-> di::Result< ProcessHandle >
auto with_controlling_tty(int fd) &&-> Process
Definition process.h:94
auto with_optional_current_working_directory(di::Path path) &&-> Process
Attempt to spawn the process with this directory, but continue on failure.
Definition process.h:113
auto with_file_open(i32 fd, di::Path path, OpenMode open_mode, u16 create_mode=0666) &&-> Process
Definition process.h:73
auto spawn_and_wait() &&-> di::Result< ProcessResult >
Definition process.h:133
auto with_tty_window_size(int fd, tty::WindowSize const &size) &&-> Process
Definition process.h:89
auto with_new_session() &&-> Process
Definition process.h:99
auto with_current_working_directory(di::Path path) &&-> Process
Spawn the process with the provided working directory.
Definition process.h:120
Process(di::Vector< di::TransparentString > arguments)
Definition process.h:71
Definition error.h:7
Definition process.h:14
void exit_process(int status_code)
auto get_hostname() -> di::Result< di::TransparentString >
Get the hostname of the current system.
void install_dummy_signal_handler(Signal signal)
auto mask_signal(Signal signal) -> di::Result< void >
auto get_environment() -> di::TreeMap< di::TransparentString, di::TransparentString > const &
Get the environment variables, as a read-only map.
auto get_program_name() -> di::PathView
Get the executed program name (argv[0])
auto wait_for_signal(Signal signal) -> di::Result< Signal >
void exit_thread()
Exit the currently executing thread.
pid_t ProcessId
Definition platform_process.h:7
OpenMode
Definition sync_file.h:111
Signal
Definition platform_process.h:9
Definition tty.h:7