6. 封装 system 函数

TOC

1. API

#include <stdlib.h>


int system(const char *command);

注:

  1. 这个函数的作用相当于,在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函数的流程

  1. fork 生成一个子进程。
  2. 在子进程执行 execl("/bin/sh","sh","-c" command,(char*)0);
  3. waitpid

返回值

  1. 如果fork失败了,或者waitpid返回除了EINTR之外的错误,system返回 -1;
  2. execl执行失败,其返回值如同shell执行了"exit(127)" 一样。
  3. 如果上述三步都执行成功,那么,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;  
}
posted @ 2020-03-23 15:58  standardzero  阅读(206)  评论(0编辑  收藏  举报