У меня есть функция для запуска процесса, а затем возвращаю код stdout и exit. Однако я заметил, что он утверждает, что каждый процесс возвращает код выхода из 1. Я управляю выведенным исполняемым файлом, и я распечатал его для вывода кода выхода, поэтому я подтвердил, что, когда он «не удался», он фактически возвращается 0 из main
. Я также вызвал исполняемый файл непосредственно из оболочки и подтвердил ожидаемый код stdout и exit (0). Таким образом, ошибка должна лежать на стороне вызывающего абонента. Я также подтвердил, что WIFEXITED не возвращает false - он возвращает true, как если бы ребенок нормально выходил (что он и сделал).waitpid() дает неверный код выхода
Этот код работал отлично, прежде чем мне нужно было записать 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(), дающий мне этот странный результат и как я могу его исправить?
Код завершения выполняемого процесса находится в тексте 'std_out', а не' result.exitcode'. Отделение печати никогда не выполняется, если 'WIFEXITED (status)' false в любом случае, поэтому мне было бы невозможно распечатать результат этого назначения. – Puppy
Это выглядит довольно подозрительно. 'Const_cast (& cargs [0])' –
Не знаете, почему аргументы должны быть изменены для execve, но я все равно заменяю процесс, поэтому мне не важно состояние памяти вектора. – Puppy