popen函数及输出错误信息

来源:互联网 发布:2012年网络流行歌曲 编辑:程序博客网 时间:2024/06/11 09:52
#include <cstdio>       // popen, printf, snprintf#include <sys/wait.h>   // WIFEXITED() WEXITSTATUS()#include <errno.h>      // extern int errno;#include <string>#include <cstring>#include <cstdlib>#include <cassert>#define MAX_SIZE (1024)bool exec_cmd(const char* command, std::string& errmsg){    assert(command);    char buffer[MAX_SIZE] = {'\0'};    std::string final_msg;    // the exit status of the command.    int rc = 0;     // I/O redirection.     char cmd[MAX_SIZE] = {'\0'};    snprintf(cmd, sizeof(cmd), "%s 2>&1", command);    FILE *fp = popen(cmd, "r");    if(NULL == fp)    {   // if fork(2) or pipe(2) calls fail, or cannot callocate memory.        // it does not set errno if memory allocation fails.        // if the underlying fork(2) or pipe(2) fails, errno is set        // appropriately.        // if the type arguments is invalid, and this condition is detected,        // errno is set to EINVAL.        snprintf(buffer, sizeof(buffer),                 "popen failed. %s, with errno %d.\n", strerror(errno), errno);        final_msg = buffer;        errmsg = final_msg.c_str();        return false;    }    char result[MAX_SIZE] = {'\0'};    std::string child_result;    while(fgets(result, sizeof(result), fp) != NULL)    {        // remove the '\n' to make output more beautiful        if('\n' == result[strlen(result)-1])        {            result[strlen(result)-1] = '\0';        }        snprintf(buffer, sizeof(buffer),                "[%s]: %s \r\n", command, result);        child_result += buffer;    }    // waits for the associated process to terminate and returns     // the exit status of the command as returned by wait4(2).    rc = pclose(fp);    if(-1 == rc)    {   // return -1 if wait4(2) returns an error, or some other error is detected.        // if pclose cannot obtain the child status, errno is set to ECHILD.        final_msg += child_result;        if(ECHILD==errno) {            final_msg += "pclose cannot obtain the child status.\n";        }        else {            snprintf(buffer, sizeof(buffer),                    "Close file failed. %s, with errno %d.\n", strerror(errno), errno);            final_msg += buffer;        }        errmsg = final_msg.c_str();        return false;    }    // TODO: warning 'file descriptor leaked#if 0    if(WIFEXITED(rc)!=0) {        printf("maybe cause file descriptor leaked.\n");    }#endif    // child process exit status.    int status_child = WEXITSTATUS(rc);    // the success message is here.    final_msg += child_result;    snprintf(buffer, sizeof(buffer),            "[%s]: command exit status [%d] and child process exit status [%d].\r\n",            command, rc, status_child);    final_msg += buffer;    errmsg = final_msg.c_str();    if(status_child==0) {         // child process exits SUCCESS.        return true;    }    else {          // child process exits FAILED.        return false;    }}bool getCmdPath(const char* cmd, String& path){    if (cmd == NULL || strlen(cmd) == 0)        return false;    string command = "which ";    command += cmd;    FILE* pf = popen(command.c_str(), "r");    if (pf) {        char buf[100];        memset(buf, '\0', sizeof(buf));        fgets(buf, sizeof(buf), pf);        pclose(pf);        //return the path        path = buf;        return true;    } else {        return false;    }}


调用popen函数,执行shell 命令,并输出错误信息。