- 论坛徽章:
- 0
|
代码如下:
static INT32 exec_cmd(CHAR *command, INT32 iTimeOut)
{
INT32 wait_val ,iRet = START_PROGRAM_FAILED ;
INT32 pid, timeout ;
__sighandler_t save_quit, save_int, save_chld;
DWORD dwTmpTicks = 0;
DWORD dwUsedTicks = 0;
if ((command == 0) && ( iTimeOut <= 0))
return 1;
timeout = iTimeOut / 10 ;
save_quit = signal(SIGQUIT, SIG_IGN);
save_int = signal(SIGINT, SIG_IGN);
save_chld = signal(SIGCHLD, SIG_DFL);
if ((pid = vfork()) < 0)
{
signal(SIGQUIT, save_quit);
signal(SIGINT, save_int);
signal(SIGCHLD, save_chld);
return -1;
}
if (pid == 0)
{
signal(SIGQUIT, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
execl("/bin/sh", "sh", "-c", command, (char *) 0);
_exit(127);
}
/* Signals are not absolutly guarenteed with vfork */
signal(SIGQUIT, SIG_IGN);
signal(SIGINT, SIG_IGN);
dwTmpTicks = GetCurrentTicks();
while (1)
{
if (wait4(pid, &wait_val, WNOHANG, 0) == -1)
{
if (errno == ECHILD)
{
iRet = 0;
break ;
}
}
timeout -- ;
usleep(1);
if ( 0 >= timeout)
{
dwUsedTicks = GetCurrentTicks() - dwTmpTicks;
printf(LOG_LEVEL_ERROR,"exec_cmd [%d] : %s use time -- [%d] ticks timeout ! \n",
pid, command, dwUsedTicks);
if (0 != kill(pid,SIGKILL))
{
printf(LOG_LEVEL_ERROR,"exec_cmd[%d]:kill timeout process[%s] failed errno[%d]\n",
pid,command,errno);
}
else
{
printf("csp_exec_cmd[%d]:kill timeout process[%s] sucess errno[%d]\n",
pid,command,errno);
}
while(1)
{
if (wait4(pid, &wait_val, WNOHANG, 0) == -1)
{
if (errno == ECHILD)
{
printf("no child exist\n");
break;
}
}
}
break;
}
}
signal(SIGQUIT, save_quit);
signal(SIGINT, save_int);
signal(SIGCHLD, save_chld);
return iRet;
}
这个代码是根据system函数来改写的,就是来达到如果子进程时间很长,我就直接杀掉它退出,
但是问题是execl("/bin/sh", "sh", "-c", command, (char *) 0);这种方式又会fork一个子进程
如果command进程写的是一个死循环的函数,这就会导致父进程只会回收其子进程的资源,其孙子进程
在超时后就变成init的子进程了,然后在那一直循环,这是我所不希望的。
我希望超时后子进程和孙子进程都一起退出。
曾想过用execvp这种方法,但是execvp不支持一些特殊的shell字符,所以有没有方法让父进程知道孙子进程的pid呢? |
|