只需使用一根管道收集两个:
std::string qx(const std::vector<std::string>& args) {
int output[2];
pipe(output);
const pid_t pid = fork();
if (!pid) {
// collect both stdout and stderr to the one pipe
close(output[0]);
dup2(output[1], STDOUT_FILENO);
dup2(output[1], STDERR_FILENO);
close(output[1]);
std::vector<char*> vc(args.size() + 1, NULL);
for (size_t i = 0; i < args.size(); ++i) {
vc[i] = const_cast<char*>(args[i].c_str());
}
execvp(vc[0], &vc[0]);
// if execvp() fails, we do *not* want to call exit()
// since that can call exit handlers and flush buffers
// copied from the parent process
_exit(0);
}
close(output[1]);
std::string out;
const int buf_size = 4096;
char buffer[buf_size];
do {
errno = 0;
const ssize_t r = read(output[0], buffer, buf_size);
if (r > 0) {
out.append(buffer, r);
}
} while (errno == EAGAIN || errno == EINTR);
请注意,您的原始代码不收集孩子的
stderr
输出。孩子写得够吗
标准错误
如果管道填满,子进程可能会阻塞。