system函数
1、system函数学习
定义函数
// param: cmd命令字符串
// return: -1:出现错误, 0:调用成功但是没有出现子进程, 127:调用/bin/sh时失败, >0:成功//退出的子进程的id
int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL)
{
return (1);
}
if((pid = fork())<0)
{
status = -1;
}
else if(pid = 0)
{
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127); //子进程正常执行则不会执行此语句
}
else //父进程
{
while(waitpid(pid, &status, 0) < 0)
{
if(errno != EINTR)
{
status = -1; //如果waitpid被信号中断,则返回-1
break;
}
}
}
return status;
}
因此system()实际是执行三个步骤:
1、fork一个子进程
2、子进程中调用exec函数去执行cmdstring
3、在父进程中调用waitpid去等待子进程结束
system函数会阻塞等待子进程的结束
判断一个system函数调用shell脚本是否正常结束的方法应该是如下3个条件同时成立:
(1)-1 != status
(2)WIFEXITED(status) != 0 // 子进程正常退出
(3) WEXITSTATUS(status)是否为子进程返回值
如果在system()调用前,SIGCHID信号被设置为 SIG_IGN, waitpid()函数有可能因为捕捉不到子进程状态信息而阻塞,并且报ECHILD错误,可以用如下方法使用
sighandler_t old_handler; old_handler = signal(SIGCHLD, SIG_DFL); // SIG_DFL 恢复默认行为, SIG_IGN 屏蔽该信号 ret = system(cmdstring); signal(SIGCHLD, old_handler);

浙公网安备 33010602011771号