gpt4 book ai didi

c++ - 重定向标准输出时调用 dup2 失败

转载 作者:太空狗 更新时间:2023-10-29 21:12:34 24 4
gpt4 key购买 nike

我已经为这个问题苦苦挣扎了一段时间。我正在尝试围绕运行子进程编写一个 C++ 类。我正在使用 fork()pipe()dup2()execv() 启动一个子进程并将其 stdout 和 stderr 重定向到父进程。据我所知,一切正常,直到 dup2() 被调用并且它因 EINVAL 而失败(在 macOS 上,我不认为这是允许的错误类型在 Linux 中)。如果我删除管道周围的所有逻辑,该类将按预期工作。

类声明:

class PosixSubprocess : public Subprocess {
std::string _cmd = {};
std::string _stdout = "";
std::string _stderr = "";
std::vector<std::string> _args = {};
long _pid = -1;
int _status = -1;

public:
void cmd(std::string val) override;
void addArg(std::string val) override;
void run() override;

int status() const override;
std::string out() const override;
std::string err() const override;
};

run()的定义:

void PosixSubprocess::run() {
std::array<int, 2> stdoutPipe = {};
std::array<int, 2> stderrPipe = {};

if (pipe(stdoutPipe.data()) < 0)
{
throw std::runtime_error("Subprocess: failed to create pipes. Errno: " + std::to_string(errno));
}

if (pipe(stderrPipe.data()) < 0)
{
throw std::runtime_error("Subprocess: failed to create pipes. Errno: " + std::to_string(errno));
}

_pid = fork();

if (_pid == 0) {

if (dup2(stderrPipe[1], STDERR_FILENO)) {
std::cout << "Subprocess: failed to redirect stderr. Errno " << errno << '\n';
exit(errno);
}
if (dup2(stdoutPipe[1], STDOUT_FILENO)) {
std::cout << "Subprocess: failed to redirect stdout. Errno " << errno << '\n';
exit(errno);
}
close(stdoutPipe[0]);
close(stdoutPipe[1]);
close(stderrPipe[0]);
close(stderrPipe[1]);

auto argv = std::make_unique<char*[]>(_args.size() + 1);
argv[_args.size()] = nullptr;

for (size_t i = 0; i < _args.size(); ++i) {
argv[i] = &(_args[i].front());
}

if(execvp(_cmd.c_str(), argv.get())) {
std::cerr << "Subprocess: failed to launch. Errno " << errno << '\n';
exit(errno);
}
} else if (_pid > 0) {
close(stdoutPipe[1]);
close(stderrPipe[1]);

std::array<char, 1024> buf;
auto appendPipe = [&buf](int fd, std::string& str) {
ssize_t nBytes = 0;
do {
nBytes = read(fd, buf.data(), buf.size());
str.append(buf.data(), nBytes);
if (nBytes) std::cout << nBytes << '\n';
} while (nBytes > 0);
};

while(!waitpid(_pid, &_status, WNOHANG)) {
appendPipe(stdoutPipe[0], _stdout);
appendPipe(stdoutPipe[0], _stderr);
}
} else {
close(stdoutPipe[0]);
close(stdoutPipe[1]);
close(stderrPipe[0]);
close(stderrPipe[1]);

throw std::runtime_error("Subprocess: fork failed.");
}
}

对于这里的代码墙,我很抱歉,我不能肯定地说与这个问题无关。

最佳答案

来自 dup2's manual page:

RETURN VALUE

Upon successful completion a non-negative integer, namely the file descriptor, shall be returned; otherwise, -1 shall be returned and errno set to indicate the error.

因为很明显,dup2() 返回原始文件被复制到的文件描述符,并且它是非零的,所以显示的代码认为这是一个错误。

错误条件由返回值指示。

关于c++ - 重定向标准输出时调用 dup2 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46919546/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com