24 #include <sys/types.h> 31 #define READ_BUFFER_SIZE 1024 35 const std::string &_executable,
36 const std::list<std::string> &_args):
37 std::iostream(&buffer),
38 executable(_executable),
53 HANDLE hOutputReadTmp, hOutputRead, hOutputWrite;
54 HANDLE hInputWriteTmp, hInputRead, hInputWrite;
56 SECURITY_ATTRIBUTES sa;
58 sa.nLength=
sizeof(SECURITY_ATTRIBUTES);
59 sa.lpSecurityDescriptor=NULL;
60 sa.bInheritHandle=
TRUE;
63 if(!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
67 if(!DuplicateHandle(GetCurrentProcess(), hOutputWrite,
68 GetCurrentProcess(), &hErrorWrite, 0,
69 TRUE, DUPLICATE_SAME_ACCESS))
73 if(!CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0))
77 if(!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp,
81 DUPLICATE_SAME_ACCESS))
84 if(!DuplicateHandle(GetCurrentProcess(), hInputWriteTmp,
88 DUPLICATE_SAME_ACCESS))
91 if(!CloseHandle(hOutputReadTmp) || !CloseHandle(hInputWriteTmp))
97 ZeroMemory(&si,
sizeof(STARTUPINFO));
98 si.cb=
sizeof(STARTUPINFO);
99 si.dwFlags=STARTF_USESTDHANDLES;
100 si.hStdOutput=hOutputWrite;
101 si.hStdInput=hInputRead;
102 si.hStdError=hErrorWrite;
106 for(
const auto &s :
args)
109 LPWSTR lpCommandLine =
new wchar_t[command.length()+1];
112 wcscpy_s(lpCommandLine, command.length()+1, command.c_str());
114 wcsncpy(lpCommandLine, command.c_str(), command.length()+1);
117 BOOL ret=CreateProcessW(NULL, lpCommandLine, NULL, NULL,
TRUE,
118 CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
120 delete lpCommandLine;
137 if(pipe(in)==-1 || pipe(out)==-1)
147 dup2(in[0], STDIN_FILENO);
148 dup2(out[1], STDOUT_FILENO);
150 char **_argv=
new char * [
args.size()+2];
156 for(std::list<std::string>::const_iterator
160 _argv[i]=strdup(a_it->c_str());
162 _argv[
args.size()+1]=
nullptr;
199 if(WaitForSingleObject(pi.hProcess, INFINITE)==WAIT_FAILED)
202 GetExitCodeProcess(pi.hProcess, &status);
209 result=waitpid(
pid, &status, WUNTRACED);
213 return WEXITSTATUS(status);
220 proc_in(INVALID_HANDLE_VALUE),
221 proc_out(INVALID_HANDLE_VALUE)
223 proc_in(STDOUT_FILENO),
224 proc_out(STDIN_FILENO)
236 if(
proc_in!=INVALID_HANDLE_VALUE)
257 std::streambuf::int_type character)
264 WriteFile(
proc_in, &buf, 1, &len, NULL);
266 int len=write(
proc_in, &buf, 1);
278 const char* str, std::streamsize count)
282 WriteFile(
proc_in, str, (DWORD)count, &len, NULL);
285 return write(
proc_in, str, count);
293 return traits_type::eof();
296 return traits_type::to_int_type(*gptr());
301 return traits_type::eof();
305 return traits_type::eof();
308 setg(eback(), eback(), eback()+(
sizeof(
char_type)*len));
311 return traits_type::eof();
313 return traits_type::to_int_type(*gptr());
318 char *target, std::streamsize count)
322 if(count <= available)
324 memcpy(target, gptr(), count *
sizeof(
char_type));
330 memcpy(target, gptr(), available *
sizeof(
char_type));
336 return (available +
xsgetn(target+available, count-available));
346 return egptr()-gptr();
355 int main(
int argc,
char** argv)
357 std::string command(
"cat");
358 std::list<std::string> arguments;
361 if(process.run() < 0)
364 process <<
"xxx\n\n";
367 for(
int i=0; i<3; ++i)
370 std::cout <<
"Answer: " << token <<
'\n';
373 return process.wait();
pipe_streamt(const std::string &_executable, const std::list< std::string > &_args)
Constructor for external process.
int wait()
Wait for the process to terminate.
int_type overflow(int_type)
write one character to the piped process
std::wstring widen(const char *s)
int_type underflow()
read a character from the piped process
std::list< std::string > args
std::streamsize xsputn(const char *, std::streamsize)
write a number of character to the piped process
std::streamsize xsgetn(char *, std::streamsize)
read a number of characters from the piped process
filedescriptor_streambuft buffer
filedescriptor_streambuft()
Constructor.
~filedescriptor_streambuft()
Destructor.
A stdin/stdout pipe as STL stream.
std::streamsize showmanyc()
determine number of available characters in stream
bitvector_typet char_type()
int run()
Starts an external process.