72inline void read_pipe(pid_t child_pid,
int pipe_fd, std::ostream&
stream, std::filesystem::path
const& path_file_log)
79 , [](std::string
const& s) {
logger(
"D::STD(OUT|ERR)::{}", s);
return s; }
91template<
typename Stream>
94 if constexpr (std::is_same_v<Stream, std::istream>)
96 return (&
stream == &std::cin);
98 else if constexpr (std::is_same_v<Stream, std::ostream>)
100 return (&
stream == &std::cout) or (&
stream == &std::cerr);
114template<
typename Stream>
119 int idx_child = is_istream ? 0 : 1;
120 int idx_parent = is_istream ? 1 : 0;
123 return_if(close(pipe[idx_parent]) == -1,,
"E::pipe[{}]: {}}", idx_parent, strerror(errno));
128 close(pipe[idx_child]);
133 return_if(dup2(pipe[idx_child], fileno) == -1,,
"E::dup2(pipe[{}], {}): {}", idx_child, fileno, strerror(errno));
134 return_if(close(pipe[idx_child]) == -1,,
"E::pipe[{}]: {}", idx_child, strerror(errno));
148template<
typename Stream>
154 std::filesystem::path
const& path_file_log)
158 int idx_parent = is_istream ? 1 : 0;
159 int idx_child = is_istream ? 0 : 1;
162 return_if(close(pipe[idx_child]) == -1, std::nullopt,
"E::pipe[{}]: {}", idx_child, strerror(errno));
167 close(pipe[idx_parent]);
172 if constexpr (std::is_same_v<Stream, std::istream>)
175 return std::jthread(
write_pipe, child_pid, pipe[idx_parent], std::ref(
stream));
180 return std::jthread(
read_pipe, child_pid, pipe[idx_parent], std::ref(
stream), path_file_log);
204inline std::vector<std::jthread>
setup(
210 std::ostream& stdout,
211 std::ostream& stderr,
212 std::filesystem::path
const& path_file_log)
214 std::vector<std::jthread> threads;
219 if (
auto t =
pipes_parent(pid,
true, pipestdin, stdin, path_file_log))
221 threads.push_back(std::move(*t));
223 if (
auto t =
pipes_parent(pid,
false, pipestdout, stdout, path_file_log))
225 threads.push_back(std::move(*t));
227 if (
auto t =
pipes_parent(pid,
false, pipestderr, stderr, path_file_log))
229 threads.push_back(std::move(*t));
236 pipes_child(
false, pipestdout, stdout, STDOUT_FILENO);
237 pipes_child(
false, pipestderr, stderr, STDERR_FILENO);
241 logger(
"E::Invalid negative pid for pipe setup");
File descriptor redirection helpers.
Value< void > redirect_fd_to_stream(pid_t ppid, int fd_src, std::ostream &stream_dst, std::function< std::string(std::string const &)> transform=[](std::string e) -> std::string { return e;})
Redirects the output of a file descriptor to a stream.
Value< void > redirect_stream_to_fd(pid_t ppid, std::istream &stream_src, int fd_dst)
Redirects the output of a stream to a file descriptor.
A library for file logging.
#define logger(fmt,...)
Compile-time log level dispatch macro with automatic location capture.
Simplified macros for common control flow patterns with optional logging.
void set_sink_file(fs::path const &path_file_sink)
Sets the sink file of the logger.
Inter-process pipe management.
void read_pipe(pid_t child_pid, int pipe_fd, std::ostream &stream, std::filesystem::path const &path_file_log)
Read from a pipe file descriptor and write to an output stream.
void pipes_child(bool is_istream, int pipe[2], Stream &stream, int fileno)
Setup pipe for child process (unified for stdin/stdout/stderr)
void write_pipe(pid_t child_pid, int pipe_fd, std::istream &stream)
Write from an input stream to a pipe file descriptor.
std::optional< std::jthread > pipes_parent(pid_t child_pid, bool is_istream, int pipe[2], Stream &stream, std::filesystem::path const &path_file_log)
Setup pipe for parent process (unified for stdin/stdout/stderr)
std::vector< std::jthread > setup(pid_t pid, int pipestdin[2], int pipestdout[2], int pipestderr[2], std::istream &stdin, std::ostream &stdout, std::ostream &stderr, std::filesystem::path const &path_file_log)
Handle pipe setup for both parent and child processes.
bool is_standard_stream(Stream &stream)
Check if a stream is a standard stream (std::cin, std::cout, or std::cerr)
Custom stream redirection for child process stdio.
Child process management and execution.
Stream
Stream redirection modes for child process stdio.