Skip to content

Instantly share code, notes, and snippets.

@jweyrich
Last active April 18, 2022 08:34
Show Gist options
  • Save jweyrich/2990547 to your computer and use it in GitHub Desktop.
Save jweyrich/2990547 to your computer and use it in GitHub Desktop.
popen + streambuf
#include <cstdio>
#include <iostream>
#include <fstream>
#define BUFFER_SIZE 1024
class popen_streambuf : public std::streambuf {
public:
popen_streambuf()
: _fp(NULL)
, _buffer(NULL) {
}
~popen_streambuf() {
close();
if (_buffer != NULL)
delete [] _buffer;
}
popen_streambuf* open(const char *command, const char *mode) {
close();
_fp = popen(command, mode);
if (_fp == NULL)
return NULL;
_buffer = new char_type[BUFFER_SIZE];
if (_buffer == NULL) {
close();
return NULL;
}
setg(_buffer, _buffer, _buffer);
return this;
}
void close() {
if (_fp != NULL) {
pclose(_fp);
_fp = NULL;
}
}
std::streamsize xsgetn(char_type *ptr, std::streamsize n) {
std::streamsize got = showmanyc();
if (n <= got) {
memcpy(ptr, gptr(), n * sizeof(char_type));
gbump(n);
return n;
}
memcpy(ptr, gptr(), got * sizeof(char_type));
gbump(got);
if (traits_type::eof() == underflow()) {
return got;
}
return (got + xsgetn(ptr + got, n - got));
}
int_type underflow() {
if (gptr() == 0)
return traits_type::eof();
if (gptr() < egptr())
return traits_type::to_int_type(*gptr());
size_t len = fread(eback(), sizeof(char_type), BUFFER_SIZE, _fp);
setg(eback(), eback(), eback() + (sizeof(char_type) * len));
if (0 == len)
return traits_type::eof();
return traits_type::to_int_type(*gptr());
}
std::streamsize showmanyc() {
if (gptr() == 0) {
return 0;
}
if (gptr() < egptr()) {
return egptr() - gptr();
}
return 0;
}
private:
FILE *_fp;
char_type *_buffer;
};
int main(int argc, char *argv) {
std::ofstream output;
output.open("bla.txt");
popen_streambuf popen_buf;
if (popen_buf.open("ps auxww", "r") == NULL) {
std::cerr << "Error..." << std::endl;
return 1;
}
output << &popen_buf;
// Use the aline above, or:
// char buffer[256];
// std::istream input(&popen_buf);
// while (input.read(buffer, 256)) {
// output << buffer;
// }
output.close();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment