在
Linux 3.0 / C下:
我想要一个功能,执行以下操作:
string f(string s) { string r = system("foo < s"); return r; }
显然上述不行,但你得到这个想法.我有一个字符串,我想通过作为应用程序“foo”的子进程执行的标准输入,然后我想将其标准输出记录到字符串r,然后返回.
解决方法
eerpini提供的代码无法正常工作.注意,例如,之后使用在父项中关闭的管道结束.看着
close(wpipefd[1]);
并且随后写入关闭的描述符.这只是转置,但是它显示这个代码从未被使用过.以下是我测试过的一个版本.不幸的是,我改变了代码风格,所以这不被接受为编辑eerpini的代码.
唯一的结构性变化是我只重定向孩子中的I / O(请注意,dup2调用仅在子路径中)这是非常重要的,因为否则父进程的I / O会被弄乱.感谢eerpini的初步答案,我用来开发这个答案.
#define PIPE_READ 0 #define PIPE_WRITE 1 int createChild(const char* szCommand,char* const aArguments[],char* const aEnvironment[],const char* szMessage) { int aStdinPipe[2]; int aStdoutPipe[2]; int nChild; char nChar; int nResult; if (pipe(aStdinPipe) < 0) { perror("allocating pipe for child input redirect"); return -1; } if (pipe(aStdoutPipe) < 0) { close(aStdinPipe[PIPE_READ]); close(aStdinPipe[PIPE_WRITE]); perror("allocating pipe for child output redirect"); return -1; } nChild = fork(); if (0 == nChild) { // child continues here // redirect stdin if (dup2(aStdinPipe[PIPE_READ],STDIN_FILENO) == -1) { perror("redirecting stdin"); return -1; } // redirect stdout if (dup2(aStdoutPipe[PIPE_WRITE],STDOUT_FILENO) == -1) { perror("redirecting stdout"); return -1; } // redirect stderr if (dup2(aStdoutPipe[PIPE_WRITE],STDERR_FILENO) == -1) { perror("redirecting stderr"); return -1; } // all these are for use by parent only close(aStdinPipe[PIPE_READ]); close(aStdinPipe[PIPE_WRITE]); close(aStdoutPipe[PIPE_READ]); close(aStdoutPipe[PIPE_WRITE]); // run child process image // replace this with any exec* function find easier to use ("man exec") nResult = execve(szCommand,aArguments,aEnvironment); // if we get here at all,an error occurred,but we are in the child // process,so just exit perror("exec of the child process"); exit(nResult); } else if (nChild > 0) { // parent continues here // close unused file descriptors,these are for child only close(aStdinPipe[PIPE_READ]); close(aStdoutPipe[PIPE_WRITE]); // Include error check here if (NULL != szMessage) { write(aStdinPipe[PIPE_WRITE],szMessage,strlen(szMessage)); } // Just a char by char read here,you can change it accordingly while (read(aStdoutPipe[PIPE_READ],&nChar,1) == 1) { write(STDOUT_FILENO,1); } // done with these in this example program,you would normally keep these // open of course as long as you want to talk to the child close(aStdinPipe[PIPE_WRITE]); close(aStdoutPipe[PIPE_READ]); } else { // Failed to create child close(aStdinPipe[PIPE_READ]); close(aStdinPipe[PIPE_WRITE]); close(aStdoutPipe[PIPE_READ]); close(aStdoutPipe[PIPE_WRITE]); } return nChild; }