Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

execl из форкнутого потомка

39K
26 мая 2009 года
imax_
20 / / 01.05.2009
Доброго, есть код, который должен создавать потомка процесса и из этого потомка вызывать стороннюю программу в данном случае sort, имя сортируемого файла и доп ключ принимаем из консоли, строка запска execl (SHELL, argv[0], argv[1], NULL); в потомке. Компилируется без ошибок, при выполнении программы не доходит до этой сторки execl (SHELL, argv[0], argv[1], NULL);

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
}


}



спасибо за внимание.
39K
26 мая 2009 года
imax_
20 / / 01.05.2009
подправил код, теперь sort работает

[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 нет чёткого понимания. подскажите.
спасибо.
2
26 мая 2009 года
squirL
5.6K / / 13.08.2003
Цитата: imax_

1) pid=fork()
породил в памяти новый процесс который идентичен текущему "запущеной программе orderfile.c" отличается лишь PID. операционная система переключилась на вновь созданый процесс во вновь созданом "дочернем процессе" был отработан if(pid == 0) ибо как гласит man дочерний процесс в качестве аргумента дескриптора pid_t получает 0.
После чего управление переместилось в процесс родитея где был получе pid поломка и отработало условие if(pid != 0).
всё ли верно изложил? подправьте дополните, спасибо.


не совсем.
после fork - создается новый процесс, который, за некоторыми небольшими исключениями - точная копия родителя. какие исключения - man 2 fork.
ОС никуда не переключается - порядок выполнения этих двух процессов - произволен и зависит от планировщика ОС. ннасчет PID все верно.

Цитата: imax_

по поводу wait нет чёткого понимания. подскажите.
спасибо.


передайте wait указатель на int. это будет переменная, которая будет хранить статус возврата потомка. этот int* потом можно обработать макросами (см. man 2 wait.
отмечу также, что, как вы видите - wait не в курсе, завершения какого потомка мы ожидаем. поэтому, если вы форкаете много процессов, лучше использовать waitpid

39K
26 мая 2009 года
imax_
20 / / 01.05.2009
форкаю только одного, спасибо Вам.
2
26 мая 2009 года
squirL
5.6K / / 13.08.2003
Цитата: imax_
форкаю только одного, спасибо Вам.



в любом случае - хорошим тоном будет использование waitpid. в реальной жизни - вам придется форкать более чем одного потомка :)

39K
26 мая 2009 года
imax_
20 / / 01.05.2009
я бы с радостью, но в реальной жизни нужны PHP или жаба программеры, а С-шников хотят видить только с 5ю годами опыта кернел девелопера... так что это так сказать для души разбираюсь..
39K
26 мая 2009 года
imax_
20 / / 01.05.2009
ещё один момент, wait я так понял ждёт завершения в сек. а код возврата потомка "как он завершился" как родителю передать можно?
2
26 мая 2009 года
squirL
5.6K / / 13.08.2003
Цитата: imax_
ещё один момент, wait я так понял ждёт завершения в сек. а код возврата потомка "как он завершился" как родителю передать можно?



я же говорил, вы передаете в wait указатель int*. а потом в эту переменную сохранется статус возврата. он потом обрабатывается макросами типа

wait(&status);
....
if (WIFSIGNALED(status)) { printf("killed by signal %d\n", WTERMSIG(status));}

39K
27 мая 2009 года
imax_
20 / / 01.05.2009
поянл, Спасибо!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог