在Linux 3.0 / C ++下:
我想要一个执行以下操作的函数:
string f(string s) { string r = system("foo < s"); return r; }
显然上述方法不起作用,但是您可以理解。我有一个字符串s,我希望将其作为应用程序“ foo”的子进程执行的标准输入传递,然后将其标准输出记录到字符串r中,然后将其返回。
我应该使用linux syscall或posix函数的什么组合?
eerpini提供的代码无法正常工作。请注意,例如,之后将使用在父级中关闭的管端。看着
close(wpipefd[1]);
以及随后对该封闭描述符的写入。这只是换位,但它表明此代码从未使用过。以下是我测试过的版本。不幸的是,我更改了代码样式,因此这不接受作为eerpini代码的编辑。
唯一的结构更改是,我仅重定向子级中的I / O(请注意dup2调用仅在子级路径中。)这非常重要,因为否则父级的I / O会混乱。感谢eerpini提出的最初答案,我在开发此答案时使用了它。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #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) { exit(errno); } // redirect stdout if (dup2(aStdoutPipe[PIPE_WRITE], STDOUT_FILENO) == -1) { exit(errno); } // redirect stderr if (dup2(aStdoutPipe[PIPE_WRITE], STDERR_FILENO) == -1) { exit(errno); } // 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 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, &nChar, 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; }