为什么80%的码农都做不了架构师?>>>
#include // popen, printf, snprintf
#include // WIFEXITED() WEXITSTATUS()
#include // extern int errno;
#include
#include
#include
#include
#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 命令,并输出错误信息。