Как може главният процес да знае, че дететопроцесът не успя да изпълни файла (например няма такъв файл или директория)? Например, в следващия код, как можем да получим () да върнем нещо различно от 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()
със стойността. Сега си return
ING 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);