Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

fork() в Free BSD

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
Polkovnik



Зарегистрирован: 13.07.2005
Сообщения: 1

СообщениеДобавлено: Ср Июл 13 2005 12:45    Заголовок сообщения: fork() в Free BSD Ответить с цитатой

Господа,
Пытаюсь написать мультипоточный TCP daemon, который запускает внешнюю программу при сетевом соединении на определенный открытый порт.
При отработке accept() делаю fork() для порождения нового дочернего процесса, в котором будет производиться вызов внешней программы. При вызове внешней программы делаю еще раз fork(), и замещаю образ нового дочернего процесса при помощи execv() образом исполняемой внешней программы. В теле кода родителя делаю waitpid() для ожидания завершения дочернего процесса. Waitpid() возвращает -1 с кодом ошибки errno=ECHILD(No child processes).

При тестировании этого же кода, но без первого fork()a все прекрасно работает.

Никто не подскажет в чем может быть дело ? Можно ли несколько раз порождать fork()ом вложеные дочерние процессы и ждать их завершения внутри родителей waitpidом ?

Код вызова внешней программы:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>
#include <errno.h>

#include <setjmp.h>

#define MAX_EPRG_ARGS 10

#define MAX_LEN 5000

#define EXT_PRG_TIMEOUT 30 /* Seconds */

/* For signal processing */

pid_t pid_to_kill = (-1);

jmp_buf env;

void sig_alrm (int dummy)
{
if (pid_to_kill>0)
{
kill (pid_to_kill,9); /* Kill it */
longjmp (env,1);
}
}

int execute (char * ext_prg,
char * ext_arg,
char * ext_output,
size_t bufsize)
{
int rcode = -1;
int Pipe [2];
int status = 0;
char * ARGUMENTS [MAX_EPRG_ARGS];
char temp_str [5000];
int i=0;

int ret_wpd = -1;

char data [2];

sig_t prev;

/* Clear the buffer */

memset (ext_output,0,bufsize);

prev=signal (SIGALRM,sig_alrm);

if (setjmp(env)!=0)
{
/* Here returns longjmp */
if (pid_to_kill>0)
{
/* Return the prev sigaction */
signal (SIGALRM,prev);
snprintf (temp_str,sizeof(temp_str)-1,"execute(): Timeout waiting external program termination, killing pid: %lu",pid_to_kill);
write_log (temp_str);
close (Pipe[0]);
close (Pipe[1]);
return (-1);
}
}

if (pipe(Pipe)==-1)
{
snprintf (temp_str,sizeof(temp_str)-1,"execute(): Cannot create pipe: '%s' !\n",strerror(errno));
write_log (temp_str);
return (-1);
}

memset (&temp_str,0,sizeof(temp_str));

if ((rcode=fork ())==0) /* Child */
{
for (i=0;i<=MAX_EPRG_ARGS-1;i++) ARGUMENTS[i]=NULL;
ARGUMENTS[0]=ext_prg;
ARGUMENTS[1]=strtok (ext_arg, " \t");
if (ARGUMENTS[1]!=NULL)
{
for (i=2;i<=MAX_EPRG_ARGS-1;i++)
{
ARGUMENTS[i]=strtok (NULL, " \t");
if (ARGUMENTS[i]==NULL) break;
}
}

/* First close the read end of the pipe */

close (Pipe[0]);

/* Make a dup */

if (dup2(Pipe[1],1)==-1)
{
snprintf (temp_str,sizeof(temp_str)-1,"execute(): 'Dup2' command failed: '%s' !\n",strerror(errno));
write_log (temp_str);
close (Pipe[0]);
close (Pipe[1]);
exit (253);
}

if (execv(ext_prg,ARGUMENTS)==-1)
{
snprintf (temp_str,sizeof(temp_str)-1,"execute(): Cannot execute external programm: '%s', Error: '%s' !\n",ext_prg,strerror(errno));
write_log (temp_str);
close (Pipe[0]);
close (Pipe[1]);
exit (253); /* Parent will get return status: 253 */
}

close (Pipe[1]);

}


if (rcode==-1) /* Parent */
{
snprintf (temp_str,sizeof(temp_str)-1,"execute(): 'Fork' command failed: '%s' !\n",strerror(errno));
write_log (temp_str);
close (Pipe[0]);
close (Pipe[1]);
return -1;
}

/* Prepare for signal processing */

pid_to_kill=rcode;

alarm (EXT_PRG_TIMEOUT);


if (waitpid (rcode,&status, (WUNTRACED))==-1)
{
snprintf (temp_str,sizeof(temp_str)-1,"execute(): 'Waitpid' command failed: '%s' !\n",strerror(errno));
write_log (temp_str);
close (Pipe[0]);
close (Pipe[1]);
return -1;
}


/* First close the write end of the pipe */

close (Pipe[1]);

memset (&data,0,sizeof(data));

while (read(Pipe[0],data,1)>0)
{
if (strlen(ext_output)<(bufsize-1)) strcat (ext_output,data);
memset (&data,0,sizeof(data));
}

alarm (0); /* Stop the timer */

signal (SIGALRM,prev); /* Return the prev sigaction */

if (WIFEXITED(status))
{
rcode=WEXITSTATUS (status);
if (rcode==253) goto L1;
else
{
close (Pipe[0]);
return (rcode);
}
}

L1:
snprintf (temp_str,sizeof(temp_str)-1,"execute(): Abnormal child termination !\n");
write_log (temp_str);
close (Pipe[0]);
close (Pipe[1]);
return -1;
}


Данный код прекрасно работает, если execute() вызвать в одном процессе. Но стоит сделать fork() и вызвать execute() в childe, waitpid всегда возвращает -1 и ECHILD.

Обработчик сигнала SIGCHLD нигде явно не переопределен.

P.S Операционная система FreeBSD 5.3
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...