Я пишу программу на C ++, которая выполняет и выводит (в режиме реального времени) сценарий оболочки, make-файл или просто другую программу. Однако я хотел бы, чтобы моя программа возвращалась по-другому, когда есть ошибки или нет ошибок.
#include "execxi.h"using namespace std;int execXI::run(string command)
{
FILE *in;
char buff[512];
// is this the check for command execution exited with not 0?
if(!(in = popen(command.c_str(), "r"))){
// I want to return the exit code and error message too if any
return 1;
}
// this part echoes the output of the command that's executed
while(fgets(buff, sizeof(buff), in)!=NULL){
cout << buff;
}
pclose(in);
return 0;}
это то, что я до сих пор
Допустим, этот скрипт выполнялся make
построить программу, и она выдала ошибку, как это так
on_target_webkit_version out/Release/obj/gen/webkit_version.h
Traceback (most recent call last):
File "../build/webkit_version.py", line 107, in <module>
sys.exit(main())
File "../build/webkit_version.py", line 103, in main
return EmitVersionHeader(*sys.argv[1:])
File "../build/webkit_version.py", line 86, in EmitVersionHeader
webkit_revision = GetWebKitRevision(webkit_dir, version_file)
File "../build/webkit_version.py", line 60, in GetWebKitRevision
version_info = lastchange.FetchVersionInfo(
AttributeError: 'module' object has no attribute 'FetchVersionInfo'
make: *** [out/Release/obj/gen/webkit_version.h] Error 1
Могу ли я узнать, что это произошло с ошибкой?
Это выходит с кодом else than 0
так как это ошибка?
Это последняя часть выведена в stderr
?
Учитывая, что make
выход с кодом не 0
скажем 1
и вывод в stderr
я не могу захватить эти коды выхода и сообщение об ошибке в конце?
Как я могу захватить код выхода и stderr
после вывода результатов программы и возврата exit code
/ stderr
в функции?
Если вас интересует код ошибки, это более переносимый способ его получения, чем деление на 256:
printf("Exit code: %i\n", WEXITSTATUS(pclose(fp)));
Тем не мение, popen
Это один из способов, поэтому вы либо создаете дополнительные обходные пути с помощью обычного стиля перенаправления в оболочке, либо вы следуете этому непроверенному коду, чтобы сделать это правильно:
#include <unistd.h>
#include <stdio.h>
/* since pipes are unidirectional, we need two pipes.
one for data to flow from parent's stdout to child's
stdin and the other for child's stdout to flow to
parent's stdin */
#define NUM_PIPES 2
#define PARENT_WRITE_PIPE 0
#define PARENT_READ_PIPE 1
int pipes[NUM_PIPES][2];
/* always in a pipe[], pipe[0] is for read and
pipe[1] is for write */
#define READ_FD 0
#define WRITE_FD 1
#define PARENT_READ_FD ( pipes[PARENT_READ_PIPE][READ_FD] )
#define PARENT_WRITE_FD ( pipes[PARENT_WRITE_PIPE][WRITE_FD] )
#define CHILD_READ_FD ( pipes[PARENT_WRITE_PIPE][READ_FD] )
#define CHILD_WRITE_FD ( pipes[PARENT_READ_PIPE][WRITE_FD] )
void
main()
{
int outfd[2];
int infd[2];
// pipes for parent to write and read
pipe(pipes[PARENT_READ_PIPE]);
pipe(pipes[PARENT_WRITE_PIPE]);
if(!fork()) {
char *argv[]={ "/usr/bin/bc", "-q", 0};
dup2(CHILD_READ_FD, STDIN_FILENO);
dup2(CHILD_WRITE_FD, STDOUT_FILENO);
/* Close fds not required by child. Also, we don't
want the exec'ed program to know these existed */
close(CHILD_READ_FD);
close(CHILD_WRITE_FD);
close(PARENT_READ_FD);
close(PARENT_WRITE_FD);
execv(argv[0], argv);
} else {
char buffer[100];
int count;
/* close fds not required by parent */
close(CHILD_READ_FD);
close(CHILD_WRITE_FD);
// Write to child’s stdin
write(PARENT_WRITE_FD, "2^32\n", 5);
// Read from child’s stdout
count = read(PARENT_READ_FD, buffer, sizeof(buffer)-1);
if (count >= 0) {
buffer[count] = 0;
printf("%s", buffer);
} else {
printf("IO Error\n");
}
}
}
Код отсюда:
http://jineshkj.wordpress.com/2006/12/22/how-to-capture-stdin-stdout-and-stderr-of-child-program/
Возвращаемое значение дочернего процесса находится в верхней части
168 бит У тебя есть
разделить возвращаемое значение pclose на 256, то вы получите
искали возвращаемое значение дочернего процесса.
Получил от http://bytes.com/topic/c/answers/131694-pclose-returning-termination-status-command
Мой ответ будет pclose(in)/256
это код выхода.
Я до сих пор не знаю, как по-другому захватить stderr или sdtout, но пока не будет ответа, я приму это как свой ответ.
Спасибо за ответ по поводу кода выхода Логана.
Я считаю, что в оба конца можно получить перенаправление во временный файл:
FILE* f = popen("cmd 2>/tmp/tmpfile.txt", "r");