Last active
April 18, 2022 08:34
-
-
Save jweyrich/2990547 to your computer and use it in GitHub Desktop.
popen + streambuf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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