/ / execv и fork: информира родител, че детето не е успяло да изпълни файла - c, fork, waitpid, execv

execv и fork: уведомете родителя, че детето не е изпълнило файла - c, fork, waitpid, execv

Как може главният процес да знае, че дететопроцесът не успя да изпълни файла (например няма такъв файл или директория)? Например, в следващия код, как можем да получим () да върнем нещо различно от 0? Благодаря!

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

enum ErrorType { noError, immediateFailure, returnFailure, forkFailure };

using namespace std;

int run(void)
{
int error = noError;
//char proc[] = "/bin/uname";
char proc[] = "/usr/bin/Idontexist";
char *const params[] = {proc, NULL};

pid_t pid = fork();

printf("pid = %dn",pid);

if (pid == 0)
{
if ( execv(proc,params)==-1 )
{
error = immediateFailure;
}
printf("child: error = %dn",error);
}
else if (pid > 0)
{
/*  This is the parent process
*  incase you want to do something
*  like wait for the child process to finish
*/
int waitError;
waitpid(pid, &waitError, 0);

if ( waitError )
error = returnFailure;

printf("parent: error = %d, waitError = %dn",error,waitError);
}
else
{
error = forkFailure;
}

return error;
}

int main(void)
{
printf("run() = %dn",run());

return 0;
}

изход:

pid = 4286
pid = 0
child: error = 1
run() = 1
parent: error = 0, waitError = 0
run() = 0

Отговори:

0 за отговор № 1

Трябва да върнете кода за грешка от main, или exit() със стойността. Сега си returnING 0 от main във всички случаи и това ще бъде изходният код на детето, от което родителят получава waitpid.

Най-доброто решение е да добавите exit(error) в детския процес:

printf("child: error = %dn",error);
exit(error);

Във всеки случай използвайте цели числа вместо случайни enum константа enum. 1 и 2 са общи стойности за връщане от много UNIX команди с 1, което означава, че командата не е била успешна (например grep не намерих съвпадения) и 2+ означава, че командата наистина не е изпълнена (неправилни аргументи или такива).

bash, zsh и други черупки използват 127 като изходния код за сигнал командата не е намерена / не работи; следователно това би било препоръчително:

#define COMMAND_NOT_RUNNABLE 127

/* ... */

execv(proc, params);  // exec never returns if successful.
perror(proc);
exit(COMMAND_NOT_RUNNABLE);

0 за отговор № 2

Проблемът е обработката на грешката след execv неуспешна. Детето застава error да се immediateFailure и връща това main, Тогава main отпечатва номера на грешката и се връща 0, Но 0 означава успех, така че родителският процес смята, че детето е успяло.

Решението е да върнете номера на грешката от main, или обадете се exit в детския код, напр.

if (pid == 0)
{
execv(proc,params);
error = immediateFailure;
printf("child: error = %dn",error);
exit( error );
}

Имайте предвид, че не е необходимо да проверявате стойността на връщането execv, от execv няма да се върне, ако успее.Той ще се върне само ако не успее и винаги ще върне -1.


0 за отговор № 3

В допълнение към предложеното exit(error); трябва да дадете конкретни възможности за waitpid, Кодът ви не работи за мен, докато не променим обаждането waitpid(pid, &waitError, WUNTRACED | WCONTINUED);