21 PipeStreamBuf::PipeStreamBuf(PipeStreamBuf::Direction dir) :
26 #ifndef PHAVE_IOSTREAM 30 assert((dir == Input) || (dir == Output));
32 setg(base(), ebuf(), ebuf());
40 ~PipeStreamBuf(
void) {
48 void PipeStreamBuf::flush(
void) {
51 write_chars(
"", 0,
true);
55 void PipeStreamBuf::command(
const string cmd) {
60 int PipeStreamBuf::overflow(
int c) {
62 assert(_dir == Output);
63 std::streamsize n = pptr() - pbase();
65 write_chars(pbase(), n,
false);
71 write_chars(&ch, 1,
false);
76 int PipeStreamBuf::sync(
void) {
79 std::streamsize n = pptr() - pbase();
80 write_chars(pbase(), n,
false);
83 std::streamsize n = egptr() - gptr();
87 cerr <<
"pfstream tossed out " << n <<
" bytes" << endl;
94 int PipeStreamBuf::underflow(
void) {
95 assert(_dir == Input);
96 if ((eback() ==
nullptr) || (gptr() ==
nullptr) ||
97 (egptr() ==
nullptr)) {
99 char* buf =
new char[4096];
100 char* ebuf = &(buf[4096]);
101 setg(buf, ebuf, ebuf);
103 if (gptr() < egptr()) {
110 #ifdef PHAVE_IOSTREAM 113 size_t len = ebuf() - base();
115 char* buf =
new char[len];
116 size_t n = read_pipe(buf, len);
121 #ifdef PHAVE_IOSTREAM 122 memcpy(eback()+(len-n), buf, n);
124 memcpy(base()+(len-n), buf, n);
132 void PipeStreamBuf::write_chars(
const char* start,
int length,
bool flush) {
133 assert(_dir == Output);
134 size_t orig = _line_buffer.length();
135 string latest(start, length);
141 line = _line_buffer + latest;
145 _line_buffer += latest;
146 size_t eol = _line_buffer.rfind(
'\n', orig);
147 if (eol != string::npos) {
148 line = _line_buffer.substr(0, eol+1);
149 _line_buffer = _line_buffer.substr(eol+1);
153 size_t wrote = write_pipe(line.c_str(), line.length());
155 if (wrote != line.length())
156 cerr <<
"wrote only " << wrote <<
" of " << line.length()
157 <<
" bytes to pipe" << endl;
161 #ifndef WIN_PIPE_CALLS 177 return _pipe !=
nullptr;
186 return (_pipe ==
nullptr) && feof(_pipe);
197 open_pipe(
const string &cmd) {
198 const char *typ = (_dir == Output)?
"w":
"r";
199 _pipe = popen(cmd.c_str(), typ);
200 return (_pipe !=
nullptr);
208 if (_pipe !=
nullptr) {
218 size_t PipeStreamBuf::
219 write_pipe(
const char *data,
size_t len) {
220 size_t wrote_count = fwrite(data, 1, len, _pipe);
229 size_t PipeStreamBuf::
230 read_pipe(
char *data,
size_t len) {
231 return fread(data, 1, len, _pipe);
234 #else // WIN_PIPE_CALLS 256 return (_child_out != 0);
265 return (_child_out == 0);
276 open_pipe(
const string &cmd) {
281 if (_dir == Output) {
287 HANDLE hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
290 HANDLE hChildStdoutRd, hChildStdoutWr;
293 SECURITY_ATTRIBUTES saAttr;
294 saAttr.nLength =
sizeof(SECURITY_ATTRIBUTES);
295 saAttr.bInheritHandle = TRUE;
296 saAttr.lpSecurityDescriptor =
nullptr;
297 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
299 cerr <<
"Unable to create output pipe\n";
305 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) {
307 cerr <<
"Unable to redirect stdout\n";
309 CloseHandle(hChildStdoutRd);
310 CloseHandle(hChildStdoutWr);
316 BOOL fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
317 GetCurrentProcess(), &_child_out,
318 0, FALSE, DUPLICATE_SAME_ACCESS);
322 cerr <<
"DuplicateHandle failed\n";
324 CloseHandle(hChildStdoutRd);
325 CloseHandle(hChildStdoutWr);
328 CloseHandle(hChildStdoutRd);
334 char *cmdline =
new char[cmd.length() + 1];
335 strcpy(cmdline, cmd.c_str());
340 if (!WinExec(cmdline, 0)) {
342 cerr <<
"Unable to spawn process.\n";
351 if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) {
353 cerr <<
"Unable to restore stdout\n";
359 if (!CloseHandle(hChildStdoutWr)) {
361 cerr <<
"Unable to close write end of pipe\n";
365 return (_child_out != 0);
373 if (_child_out != 0) {
374 CloseHandle(_child_out);
383 size_t PipeStreamBuf::
384 write_pipe(
const char *data,
size_t len) {
392 size_t PipeStreamBuf::
393 read_pipe(
char *data,
size_t len) {
394 if (_child_out == 0) {
398 if (!ReadFile(_child_out, data, len, &dwRead,
nullptr)) {
407 #endif // WIN_PIPE_CALLS PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.