Я создал несколько дочерних процессов с помощью fork() и заставил их запускать исполняемый файл с помощью execl().
Я хочу проверить, есть ли какая-либо ошибка execl() (например, попытка выполнить несуществующий файл). Попытайтесь выполнить execl() все программы, и если одна из них не удалась, верните 1 до того, как start начнет общаться с любыми программами.
вот справочный код (предположим, что все настройки верны)
#DEFINE NUMBEROFCHILD 4
char** exeFile = {"./p1", "./p2", "./p3", "nonexist"); //"nonexist" is a non-exist program
int main(int argc, char** argv){
pid_t childPID [numberOfChild];
for (int i = 0; i<numberOfChild; i++) {
//setting up pipes
pid_t childPID[i] = fork();
if(childPID[i] < 0) {
//close all pipes and quit
}else if (childPID[i] == 0) {
//redirect pipe
execl(exeFile[i],"args",(char*)0;
return 1;
//I'm expecting this to return when it try to execute "nonexist"
//but it didn't and keep running successed execl()
}else {
//close un-use pipes
}
}
while(true) {
for (int i = 0; i<numberOfChild; i++) {
//communicate with childs through pipe
}
}
for (int i = 0; i<numberOfChild; i++) {
//close reminded pipes
if (waitpid(childPID[i], NULL, 0) == -1){
return 1;
}
}
return 0;
}
Эта программа по-прежнему отправляла сообщение «несуществующему» (но ничего не получала от него, как и ожидалось).
Есть ли способ достичь моей цели? Благодарю вас!
printf
передreturn 1
, чтобы увидеть, чтоexecl
не удалось. Имейте в виду, что в этот момент вы находитесь в дочернем процессе, поэтому вам нужно будет использовать каналы для обратной связи с родителем, или отправить сигнал, напримерkill(getppid(), SIG_USER1)
, или использовать любое количество других средств межпроцессного взаимодействия. - person user3386109   schedule 29.09.2016exec*
возвращает значение ошибки -1, аerrno
указывает на ошибку. Проверьте возвращаемое значениеexecl
(в основномexecl
возвращается только при ошибке). - person Pablo   schedule 29.09.2016execl
вернет 2 (ENOENT
) - person Pablo   schedule 29.09.2016execl(exeFile[i],"args",(char*)0;
неверно, не так ли?). Функцияexecl()
возвращает значение только в случае сбоя процесса exec. Без работы по настройке единственным способом для родителя узнать о сбое дочернего процесса является ожидание процесса (возможно, с помощьюwaitpid(pid, &status, WNOHANG)
) или попытка подать ему сигнал (kill(0, pid)
видит, доступен ли pid). Оба они могут столкнуться с ложными срабатываниями планирования: ребенок еще не пробовалexecl()
, но когда он это сделает, он потерпит неудачу. - person Jonathan Leffler   schedule 29.09.2016printf("errno = %d (%s)\n", errno, strerror(errno));
, чтобы получить номер ошибки. - person Pablo   schedule 29.09.2016execl()
или любой изexec*()
функций. Если он вообще возвращается, значит, произошел сбой (и возвращаемое значение равно-1
). Просто напишите код сообщения об ошибке после вызоваexec*()
. - person Jonathan Leffler   schedule 29.09.2016execl()
равно-1
, аerrno
установлено в2
илиENOENT
. - person Jonathan Leffler   schedule 29.09.2016execl
вернется только в случае сбоя. Кажется, я не правильно выразился. - person Pablo   schedule 29.09.2016execl()
, или вы хотите, чтобы родительский процесс прервал все это и вернуть 1 вызывающей стороне? - person John Bollinger   schedule 30.09.2016return 1;
послеexecl()
— или, в функции, отличной отmain()
, вызовexit(1);
или одного из его вариантов — совершенно необходим. Также должно быть напечатано сообщение об ошибке в стандартной ошибке. Но вы не можете позволить, чтобы потомок продолжал выполняться после того, как он не выполнился — это привело бы к хаосу и путанице. Проблема в том, как родитель распознает, что ребенок не смог выполнить. (Кстати, POSIX рекомендуетexit(127);
, когда команда не найдена — статус выхода для команды.) - person Jonathan Leffler   schedule 30.09.2016