21namespace ns_linux::ns_fd
24constexpr uint32_t
const SECONDS_TIMEOUT = 5;
25constexpr uint32_t
const SIZE_BUFFER_READ = 16384;
26constexpr auto const TIMEOUT_RETRY = std::chrono::milliseconds(50);
38 return_if (ppid < 0, Error(
"E::Invalid pid to wait for: {}", ppid));
39 return_if (fd_src < 0, Error(
"E::Invalid source file descriptor: {}", fd_src));
40 return_if (fd_dst < 0, Error(
"E::Invalid destination file descriptor: {}", fd_dst));
42 auto f_rw = [](
int fd_src,
int fd_dst) ->
Value<bool>
44 alignas(16)
char buf[SIZE_BUFFER_READ];
47 , std::chrono::milliseconds(100)
48 , std::span(buf,
sizeof(buf))
59 if((errno == EAGAIN) or (errno == ETIMEDOUT))
64 return Error(
"E::Failed to read from file descriptor '{}' with error '{}'"
70 return_if(::write(fd_dst, buf, n) < 0
71 , Error(
"D::Could not write to file descriptor '{}' with error '{}'", fd_dst, strerror(errno))
76 while (::kill(ppid, 0) == 0 and Pop(f_rw(fd_src, fd_dst)))
78 std::this_thread::sleep_for(std::chrono::milliseconds(50));
81 std::ignore = Pop(f_rw(fd_src, fd_dst));
97 , std::chrono::seconds(SECONDS_TIMEOUT)
102 return Error(
"E::Failed to open file '{}' with error '{}'", path_file, strerror(errno));
122 , fs::path
const& path_file)
126 , std::chrono::seconds(SECONDS_TIMEOUT)
131 return Error(
"E::Failed to open file '{}' with error '{}'", path_file, strerror(errno));
153 , std::ostream& stream_dst
154 , std::function<std::string(std::string
const&)> transform = [](std::string e) -> std::string {
return e; })
157 return_if(fd_src < 0, Error(
"E::Invalid src file descriptor"));
160 for (
alignas(16)
char buf[SIZE_BUFFER_READ]; ::kill(ppid, 0) == 0;)
166 std::string chunk(buf, n);
168 std::ranges::replace(chunk,
'\r',
'\n');
170 std::ranges::for_each(chunk
171 | std::views::split(
'\n')
172 | std::views::transform([](
auto&& e){
return std::string{e.begin(), e.end()}; })
173 | std::views::filter([](
auto const& s){
return not s.empty(); })
174 | std::views::filter([](
auto const& s){
return not std::ranges::all_of(s, ::isspace); })
175 | std::views::transform([&](
auto&& e){
return transform(e); })
176 , [&](
auto line) { stream_dst << line <<
'\n'; }
186 return_if(n < 0 and (errno != EAGAIN) and (errno != ETIMEDOUT)
187 , Error(
"E::Failed to read from file descriptor '{}' with error '{}'", fd_src, strerror(errno));
190 std::this_thread::sleep_for(TIMEOUT_RETRY);
207 using namespace std::chrono_literals;
209 alignas(16)
char buf[SIZE_BUFFER_READ];
211 return_if(fd_dst < 0, Error(
"E::Invalid src file descriptor"));
213 for(; ::kill(ppid, 0) == 0; std::this_thread::sleep_for(TIMEOUT_RETRY))
221 if (std::streamsize avail = stream_src.rdbuf()->in_avail(); avail > 0)
224 std::streamsize to_read = std::min(avail,
static_cast<std::streamsize
>(
sizeof(buf)));
225 stream_src.read(buf, to_read);
227 std::streamsize n = stream_src.gcount();
231 continue_if (n <= 0);
235 , Error(
"E::Could not write data to file descriptor '{}': {}", fd_dst, strerror(errno));
240 if (stream_src.eof())
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_file_to_fd(pid_t ppid, fs::path const &path_file, int fd_dst)
Redirects the output of a file to a file descriptor.
Value< void > redirect_fd_to_fd(pid_t ppid, int fd_src, int fd_dst)
Redirects the output of one file descriptor as input of another.
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.
Value< void > redirect_fd_to_file(pid_t ppid, int fd_src, fs::path const &path_file)
Redirects the output of a file descriptor to a file.
A library with helpers for linux operations.
int open_with_timeout(fs::path const &path_file_src, std::chrono::milliseconds timeout, int oflag)
Opens a given file with a timeout.
ssize_t write_with_timeout(int fd, std::chrono::milliseconds const &timeout, std::span< Data > buf)
Writes to the file descriptor with a timeout.
ssize_t read_with_timeout(int fd, std::chrono::milliseconds const &timeout, std::span< Data > buf)
Reads from the file descriptor with a timeout.
Enhanced expected type with integrated logging capabilities.