mirror of
https://github.com/arun11299/cpp-subprocess.git
synced 2025-08-05 04:46:21 -04:00
overload stream arguments for file pointer and new pipeline test case
This commit is contained in:
parent
6a9f0aab51
commit
f409d50c8d
4
main.cc
4
main.cc
@ -6,10 +6,10 @@ int main() {
|
||||
auto p = Popen({"./script.sh"},
|
||||
output{"out.txt"});
|
||||
|
||||
auto buf = check_output({"echo", "\"It works!\""});
|
||||
auto buf = check_output("echo Hello");
|
||||
std::cout << buf.buf.data() << " :: " << buf.length << std::endl;
|
||||
|
||||
buf = check_output("cat subprocess.hpp");
|
||||
//buf = check_output("cat subprocess.hpp");
|
||||
//std::cout << buf2.buf.data() << " :: " << buf2.length << std::endl;
|
||||
//
|
||||
|
||||
|
@ -142,6 +142,34 @@ namespace util
|
||||
return rbytes;
|
||||
}
|
||||
|
||||
template <typename Buffer>
|
||||
static int read_all(int fd, Buffer& buf)
|
||||
{
|
||||
size_t orig_size = buf.size();
|
||||
size_t increment = orig_size;
|
||||
auto buffer = buf.data();
|
||||
int total_bytes_read = 0;
|
||||
|
||||
while (1) {
|
||||
int rd_bytes = read_atmost_n(fd, buffer, buf.size());
|
||||
if (rd_bytes == increment) {
|
||||
// Resize the buffer to accomodate more
|
||||
orig_size = orig_size * 1.5;
|
||||
increment = orig_size - buf.size();
|
||||
buf.resize(orig_size);
|
||||
buffer += rd_bytes;
|
||||
total_bytes_read += rd_bytes;
|
||||
} else if (rd_bytes != -1){
|
||||
total_bytes_read += rd_bytes;
|
||||
break;
|
||||
} else {
|
||||
if (total_bytes_read == 0) return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return total_bytes_read;
|
||||
}
|
||||
|
||||
static
|
||||
std::pair<int, int> wait_for_child_exit(int pid)
|
||||
{
|
||||
@ -212,11 +240,14 @@ enum IOTYPE {
|
||||
PIPE,
|
||||
};
|
||||
|
||||
//TODO: A common base/interface for below stream structures ??
|
||||
|
||||
struct input
|
||||
{
|
||||
input(int fd): rd_ch_(fd) {}
|
||||
|
||||
input (FILE* fp):input(fileno(fp)) { assert(fp); }
|
||||
|
||||
input(const char* filename) {
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd == -1) throw OSError("File not found: ", errno);
|
||||
@ -235,6 +266,8 @@ struct output
|
||||
{
|
||||
output(int fd): wr_ch_(fd) {}
|
||||
|
||||
output (FILE* fp):output(fileno(fp)) { assert(fp); }
|
||||
|
||||
output(const char* filename) {
|
||||
int fd = open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
|
||||
if (fd == -1) throw OSError("File not found: ", errno);
|
||||
@ -253,6 +286,8 @@ struct error
|
||||
{
|
||||
error(int fd): wr_ch_(fd) {}
|
||||
|
||||
error(FILE* fp):error(fileno(fp)) { assert(fp); }
|
||||
|
||||
error(const char* filename) {
|
||||
int fd = open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
|
||||
if (fd == -1) throw OSError("File not found: ", errno);
|
||||
@ -558,6 +593,10 @@ public:
|
||||
return communicate(nullptr, 0);
|
||||
}
|
||||
|
||||
FILE* input() { return stream_.input(); }
|
||||
FILE* output() { return stream_.output();}
|
||||
FILE* error() { return stream_.error(); }
|
||||
|
||||
private:
|
||||
template <typename F, typename... Args>
|
||||
void init_args(F&& farg, Args&&... args);
|
||||
@ -932,10 +971,9 @@ namespace detail {
|
||||
// at the other end screws up, we get screwed up as well
|
||||
obuf.add_cap(out_buf_cap_);
|
||||
|
||||
int rbytes = util::read_atmost_n(
|
||||
int rbytes = util::read_all(
|
||||
fileno(stream_->output()),
|
||||
obuf.buf.data(),
|
||||
obuf.buf.size());
|
||||
obuf.buf);
|
||||
|
||||
if (rbytes == -1) {
|
||||
throw OSError("read to obuf failed", errno);
|
||||
@ -1075,4 +1113,6 @@ OutBuffer check_output(const std::string& arg, Args&&... args)
|
||||
return (detail::check_output_impl(arg, std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
// Piping Support
|
||||
|
||||
};
|
||||
|
@ -12,7 +12,17 @@ void test_input()
|
||||
std::cout << res.first.buf.data() << std::endl;
|
||||
}
|
||||
|
||||
void test_piping()
|
||||
{
|
||||
auto cat = Popen({"cat", "../subprocess.hpp"}, output{PIPE});
|
||||
auto grep = Popen({"grep", "template"}, input{cat.output()}, output{PIPE});
|
||||
auto cut = Popen({"cut", "-d,", "-f", "1"}, input{grep.output()}, output{PIPE});
|
||||
auto res = cut.communicate().first;
|
||||
std::cout << res.buf.data() << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_input();
|
||||
test_piping();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user