#pragma once #include #include #include #include #include #include #include "common.hpp" #include "utils/string.hpp" LEMONBUDDY_NS namespace io_util { inline string read(int read_fd, int bytes_to_read, int& bytes_read_loc, int& status_loc) { char buffer[BUFSIZ - 1]; if (bytes_to_read == -1) bytes_to_read = sizeof(buffer); status_loc = 0; if ((bytes_read_loc = ::read(read_fd, &buffer, bytes_to_read)) == -1) { throw system_error("Error trying to read from fd"); } else if (bytes_read_loc == 0) { status_loc = -1; } else { buffer[bytes_read_loc] = '\0'; } return {buffer}; } inline string read(int read_fd, int bytes_to_read = -1) { int bytes_read = 0; int status = 0; return read(read_fd, bytes_to_read, bytes_read, status); } inline string readline(int read_fd, int& bytes_read) { std::stringstream buffer; char char_; bytes_read = 0; while ((bytes_read += ::read(read_fd, &char_, 1)) > 0) { buffer << char_; if (char_ == '\n' || char_ == '\x00') break; } if (bytes_read == 0) { // Reached EOF } else if (bytes_read == -1) { // Read failed } else { return string_util::strip_trailing_newline(buffer.str()); } return ""; } inline string readline(int read_fd) { int bytes_read; return readline(read_fd, bytes_read); } inline size_t write(int write_fd, string data) { return ::write(write_fd, data.c_str(), strlen(data.c_str())); } inline size_t writeline(int write_fd, string data) { if (data.length() == 0) return -1; if (data.substr(data.length() - 1, 1) != "\n") return io_util::write(write_fd, data + "\n"); else return io_util::write(write_fd, data); } inline void tail(int read_fd, function callback) { int bytes_read; while (true) { auto line = io_util::readline(read_fd, bytes_read); if (bytes_read <= 0) break; callback(line); } } inline void tail(int read_fd, int writeback_fd) { tail(read_fd, [&writeback_fd](string data) { io_util::writeline(writeback_fd, data); }); } inline bool poll(int fd, short int events, int timeout_ms = 1) { struct pollfd fds[0]; fds[0].fd = fd; fds[0].events = events; ::poll(fds, 1, timeout_ms); return fds[0].revents & events; } inline bool poll_read(int fd, int timeout_ms = 1) { return poll(fd, POLLIN, timeout_ms); } inline bool poll_write(int fd, int timeout_ms = 1) { return poll(fd, POLLOUT, timeout_ms); } inline void interrupt_read(int write_fd) { char end[1] = {'\n'}; ::write(write_fd, end, 1); } } LEMONBUDDY_NS_END