Я выполняю две команды bash ps
(действительная команда bash для отображения информации о процессах) и abc
(недопустимая команда bash), используя execvp()
внутри дочернего процесса после его создания с помощью fork()
Проблема заключается в том, что когда execvp()
происходит сбой, родительский процесс берется на себя дочерним процессом, как мы можем видеть на скриншоте.
Мне пришлось дважды набрать выход, чтобы выйти из бесконечного цикла while. Что творится? Я правильно выполняю execvp()
внутри дочернего процесса, но основной (родительский) процесс берет на себя дочерний процесс?
Может ли кто-нибудь объяснить это поведение и как я могу это исправить? Если execvp()
терпит неудачу, я не хочу, чтобы этот дочерний процесс взял на себя родительский процесс. Как справиться с этим?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
int ExecCommand(char** args)
{
int childId = fork();
if (childId<0) printf("Error creating child process\n");
if (childId==0)
{
printf("Executing (%s) whose childId:%d\n", args[0], getpid());
int status=execvp(args[0],args);
printf("Failed executing %s with status %d whose childId:%d\n\n",args[0],status,getpid());
return 1;
}
else
{
int id=wait(NULL);
printf("waiting for child: %d\n\n",id);
}
}
int main()
{
char out[5] = "exit\0";
while(1)
{
printf("From Main(): pid:%d ppid:%d\n",getpid(), getppid());
printf("Enter 'exit' to exit or Just hit Enter to execute below 2 commands:");
char input[25] = {'\0'};
scanf("%24[^\n]",&input[0]);
getchar();//to remove \n from stdin
strncpy(out,input,4);
if (strcmp(out,"exit\0")==0)
{
exit(0);
}
char *cmd1[2] = {"ps", NULL}; //valid bash command
char *cmd2[2] = {"abc", NULL}; //invalid bash command
char** commands[2] = {cmd1, cmd2};
for(int i=0;i<2;i++)
{
ExecCommand(commands[i]);
}
}
return 0;
}
Выход:
Проблема в том, что если execvp
терпит неудачу, вы возвращаетесь к функции main
в дочернем процессе. Это приводит к тому, что как исходный (родительский), так и дочерний процессы будут продолжаться в цикле.
Если execvp
терпит неудачу, вам, вероятно, следует вызвать exit
, чтобы выйти из дочернего процесса.
Также обратите внимание, что в родительском процессе функция ExecCommand
вообще ничего не возвращает. Если ваш компилятор не жалуется на это, вам нужно включить больше предупреждений при сборке.
Я жду завершения дочернего процесса в другом блоке, почему он берет на себя родительский? разве это не должно закончиться само собой? Можете ли вы указать мне что-нибудь еще на эту тему для чтения. Недавно я изучил программирование с несколькими процессами, используя fork() в c. Не совсем уверен в этом.
@MudassirHussain В функции ExecCommand
вы делаете return 1;
в пути дочернего процесса. Это возвращается из функции ExecCommand
, это не выход из процесса. Вместо этого вы должны выйти из процесса, вызвав exit(1)
(например).
Хорошо, только что использовал выход (1) и он работает. Спасибо. Примет ответ.
Кстати говоря, строка
"exit\0"
на самом деле состоит из шесть символов: четыре в словеexit
, ваш нуль-терминатор и нуль-терминатор, добавленный компилятором. Кто-то или что-то когда-либо научило вас добавлять свой собственный нуль-терминатор в строки, было неправильным. И вы даже используете его непоследовательно, почему вы добавляете явный нуль-терминатор для одних строк, но не для других?