6. 封装 system 函数
1. API
#include <stdlib.h>
int system(const char *command);
注:
- 这个函数的作用相当于,在shell下执行command命令
2. 源码
int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL)
{
return (1); //如果cmdstring为空,返回非零值,一般为1
}
if((pid = fork())<0)
{
status = -1; //fork失败,返回-1
}
else if(pid == 0)
{
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在啦~~
}
else //父进程
{
while(waitpid(pid, &status, 0) < 0)
{
if(errno != EINTR)
{
status = -1; //如果waitpid被信号中断,则返回-1
break;
}
}
}
return status; //如果waitpid成功,则返回子进程的返回状态
}
注:
从源码可以分析system
函数的流程
- fork 生成一个子进程。
- 在子进程执行 execl("/bin/sh","sh","-c" command,(char*)0);
- waitpid
返回值
- 如果fork失败了,或者waitpid返回除了EINTR之外的错误,system返回 -1;
- execl执行失败,其返回值如同shell执行了"exit(127)" 一样。
- 如果上述三步都执行成功,那么,system返回值是shell的终止状态。
3. 对system进行封装
int Common_System(const char *cmd)
{
int status;
status = system(cmd);
if (-1 == status)
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "ERROR: cmd[%s], failed!", cmd);
return -1;
}
else
{
if (WIFEXITED(status))
{
if(WEXITSTATUS(status))
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "ERROR: cmd[%s], script exit code: %d, system error, failed!", cmd, WEXITSTATUS(status));
return -1;
}
}
else
{
LOG_PRINTF(LOG_LEVEL_ERROR, LOG_MODULE_SYS, "ERROR: cmd[%s], exit status = [%d], failed!", cmd, WEXITSTATUS(status));
return -1;
}
}
return 0;
}