execl из форкнутого потомка
Tesla:# ./orderfile -b orderfile.c
*******PARENT*******
PARENT: PID - 12927
PARENT: PID my CHILD 12928
PARENT: i wait to exit()...
PARENT: code exit CHILD:0
PARENT: Exit!
*******CHILD*******
CHILD: PID - 12928
CHILD: PID my PARENT - 1
Tesla:#
из-за чего, в чём проблема?
сам код:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stddef.h>
#define SHELL "sort"
int main(int argc, char* argv[4])
{
//data type
pid_t pid;
int rv;
pid=fork();
if(pid == -1)
{
perror("fork");
exit(1);
}
//this process PARENT
if(pid != 0)
{
printf("\n\n*******PARENT*******\n");
printf(" PARENT: PID - %d\n", getpid());
printf(" PARENT: PID my CHILD %d\n", pid);
printf(" PARENT: i wait to exit()...\n");
// wait(); //!!?!?!??!??!?!??!?!?!
printf(" PARENT: code exit CHILD:%d\n",WEXITSTATUS(rv));
printf(" PARENT: Exit!\n");
}
//this process CHILD
if(pid == 0)
{
printf("\n\n*******CHILD*******\n");
printf(" CHILD: PID - %d\n", getpid());
printf(" CHILD: PID my PARENT - %d\n",getppid());
printf("%s,---%s",argv[0],argv[1]);
execl (SHELL, argv[0], argv[1], NULL);
_exit (EXIT_FAILURE); //without updating flow
}
}
спасибо за внимание.
[C]
//NAME PROG orderfile.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stddef.h>
#define PATH "/usr/bin/sort"
#define SORT "sort"
int main(int argc, char* argv[])
{
//data type
pid_t pid;
int rv;
//create new process
pid=fork();
if(pid == -1)
{
perror("fork");
exit(1);
}
//this process PARENT
if(pid != 0)
{
printf("\n\n*******PARENT*******\n");
printf(" PARENT: PID - %d\n", getpid());
printf(" PARENT: PID my CHILD %d\n", pid);
printf(" PARENT: i wait to exit()...\n");
// wait(); //!!?!?!??!??!?!??!?!?!
printf(" PARENT: code exit CHILD:%d\n",WEXITSTATUS(rv));
printf(" PARENT: Exit!\n");
}
//this process CHILD
if(pid == 0)
{
printf("\n\n*******CHILD*******\n");
printf(" CHILD: PID - %d\n", getpid());
printf(" CHILD: PID my PARENT - %d\n",getppid());
printf("ARG0 - %s, ARG1 - %s ",argv[0],argv[1]);
printf("\n@@@@@@@Print file SORT:@@@@@@@\n");
execl (PATH, SORT, argv[1], argv[2], NULL);
_exit (EXIT_FAILURE); //without updating flow
}
}
[/C]
начитался манов
http://www.opennet.ru/docs/RUS/glibc/glibc-23.html
http://www.opennet.ru/docs/RUS/ipcbook/node7.html
man fork
man exec
теперь хотелось бы изложить ход понимания происходящего, верно ли всё осознаю
1) pid=fork()
породил в памяти новый процесс который идентичен текущему "запущеной программе orderfile.c" отличается лишь PID. операционная система переключилась на вновь созданый процесс во вновь созданом "дочернем процессе" был отработан if(pid == 0) ибо как гласит man дочерний процесс в качестве аргумента дескриптора pid_t получает 0.
После чего управление переместилось в процесс родитея где был получе pid поломка и отработало условие if(pid != 0).
всё ли верно изложил? подправьте дополните, спасибо.
Теперь хочу организовать механизм ожидания завершения работы потомка, в манах обнаружил что это можно реализовать используя функцию wait()
[C]
if(pid != 0)
{
printf("\n\n*******PARENT*******\n");
printf(" PARENT: PID - %d\n", getpid());
printf(" PARENT: PID my CHILD %d\n", pid);
printf(" PARENT: i wait to exit()...\n");
// wait(); //!!?!?!??!??!?!??!?!?!!!??!??!?????
printf(" PARENT: code exit CHILD:%d\n",WEXITSTATUS(rv));
printf(" PARENT: Exit!\n");
}
[/C]
котороя будет ждать возврата кода от потомка и посредством макроса WEXITSTATUS вывести его результат
но при использовании даной фции компилер ругается
orderfile.c:42: error: too few arguments to function ‘wait’
мало этой фции видите ли параметров, что за параметры? почему и зачем?
по поводу wait нет чёткого понимания. подскажите.
спасибо.
1) pid=fork()
породил в памяти новый процесс который идентичен текущему "запущеной программе orderfile.c" отличается лишь PID. операционная система переключилась на вновь созданый процесс во вновь созданом "дочернем процессе" был отработан if(pid == 0) ибо как гласит man дочерний процесс в качестве аргумента дескриптора pid_t получает 0.
После чего управление переместилось в процесс родитея где был получе pid поломка и отработало условие if(pid != 0).
всё ли верно изложил? подправьте дополните, спасибо.
не совсем.
после fork - создается новый процесс, который, за некоторыми небольшими исключениями - точная копия родителя. какие исключения - man 2 fork.
ОС никуда не переключается - порядок выполнения этих двух процессов - произволен и зависит от планировщика ОС. ннасчет PID все верно.
по поводу wait нет чёткого понимания. подскажите.
спасибо.
передайте wait указатель на int. это будет переменная, которая будет хранить статус возврата потомка. этот int* потом можно обработать макросами (см. man 2 wait.
отмечу также, что, как вы видите - wait не в курсе, завершения какого потомка мы ожидаем. поэтому, если вы форкаете много процессов, лучше использовать waitpid
в любом случае - хорошим тоном будет использование waitpid. в реальной жизни - вам придется форкать более чем одного потомка :)
я же говорил, вы передаете в wait указатель int*. а потом в эту переменную сохранется статус возврата. он потом обрабатывается макросами типа
wait(&status);
....
if (WIFSIGNALED(status)) { printf("killed by signal %d\n", WTERMSIG(status));}