[英]waitpid() gives incorrect exit code
我有一个用于启动进程,然后返回标准输出和退出代码的函数。 但是,我注意到它声称每个进程都返回退出代码1。我控制了正在执行的可执行文件,并打印了该输出以标出退出代码,因此我已经确认,当它“失败”时,实际上从main
返回0。 我还直接从外壳程序调用了可执行文件,并确认了预期的标准输出和退出代码(0)。 因此,故障必须出在呼叫者一方。 我还确认了WIFEXITED不会返回false-就像孩子正常退出一样返回true。
在我需要捕获stdout之前,这段代码可以正常工作,因此它必须与此有关。 我尝试查看“孩子已经终止”作业,但是在这种情况下没有发生-waitpid()的行为与我期望的完全一样,只是不在乎孩子在我命名时可能已经终止了。标准输出。
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
Wide::Driver::ProcessResult Wide::Driver::StartAndWaitForProcess(std::string name, std::vector<std::string> args, Util::optional<unsigned> timeout) {
int filedes[2];
pipe(filedes);
pid_t pid = fork();
if (pid == 0) {
while ((dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
freopen("/dev/null", "rw", stdin);
freopen("/dev/null", "rw", stderr);
//close(filedes[0]);
std::vector<const char*> cargs;
cargs.push_back(name.c_str());
for (auto&& arg : args)
cargs.push_back(arg.c_str());
cargs.push_back(nullptr);
execv(name.c_str(), const_cast<char* const*>(&cargs[0]));
}
std::string std_out;
close(filedes[1]);
char buffer[4096];
while (1) {
ssize_t count = read(filedes[0], buffer, sizeof(buffer));
if (count == -1) {
if (errno == EINTR) {
continue;
} else {
perror("read");
exit(1);
}
} else if (count == 0) {
break;
} else {
std_out += std::string(buffer, buffer + count);
}
}
close(filedes[0]);
int status;
ProcessResult result;
result.std_out = std_out;
waitpid(pid, &status, 0);
if (!WIFEXITED(status))
result.exitcode = 1;
else {
result.exitcode = WEXITSTATUS(status);
if (result.exitcode != 0) {
std::cout << name << " failed with code " << result.exitcode << "\n";
std::cout << "stdout: " << result.std_out;
}
}
return result;
}
为什么地球上的waitpid()会给我这个奇怪的结果,我该如何解决呢?
我已经在IRC中确认这是LLVM问题。 我打印出的进程的退出代码是我从main
返回的-静态析构函数或其他此类代码仍然可以运行并调用exit(1)
。 这是由重定向stderr引起的-因此,基本上,您不会收到错误,因为如果不重定向stderr,则不会看到问题。 因此,如果您从外壳执行,由于不会重定向stderr,因此一切都很好。
因此,尽管外壳程序和我自己的返回码一致,但实际上该过程返回的是退出码1。
显然,该问题已在树干中解决,或者应该已经解决,但我仍在使用3.6。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.