#include "Shell.h"
#include <signal.h>
#include <sys/errno.h>
#include <sys/wait.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
using namespace agent;
Shell::Shell(void)
{
}
Shell::~Shell(void)
{
}
int Shell::Execute(const string& strCmd)
{
if(strCmd.empty())
return -1;
int ret = system(strCmd.c_str());
return ret;
}
int Shell::Execute(const string& strCmd,string& strRet)
{
if(strCmd.empty())
return -1;
#ifdef WIN32
FILE* cmdPipe = _popen(strCmd.c_str(), "rt");
#else
FILE* cmdPipe = popen(strCmd.c_str(), "r");
#endif
if(!cmdPipe)
return -1;
signed char tmpStr(0);
while(true)
{
tmpStr = (char)fgetc(cmdPipe);
if(EOF == tmpStr)
{
break;
}
else
{
strRet += tmpStr;
}
}
#ifdef WIN32
_pclose(cmdPipe);
#else
pclose(cmdPipe);
#endif
return 0;
}
int Shell::Execute(const string& strCmd,string& strRet, const int nTimeout,const string strShell)
{
if(strCmd.empty())
return -1;
//signal(SIGCHLD,SIG_IGN);
string cmd = strShell;
std::string::size_type pos = strShell.find_last_of('/');
if(pos != std::string::npos){
cmd = strShell.substr(pos+1);
}
//create pid
int filedes[2];
if(pipe(filedes) < 0)
{
//printf("[Shell::Execute] pipe create error\n");
return -1;
}
//设置为非阻塞
fcntl(filedes[0], F_SETFL, O_NONBLOCK);
//fcntl(filedes[1], F_SETFL, O_NONBLOCK);
int nRe = 0;
pid_t pid = fork();
if(pid < 0)
{
//printf("[Shell::Execute] fork error\n");
return -1;
}
//child
if(pid == 0)
{
//printf("child-----------my process id is %d\n",getpid());
close(filedes[0]);
if (filedes[1] != STDOUT_FILENO)
{
dup2(filedes[1], STDOUT_FILENO);//复制文件句柄用法
dup2(filedes[1], STDERR_FILENO);
close(filedes[1]);
}
if(cmd == "perl"){
execl(strShell.c_str(), cmd.c_str(), "-e", strCmd.c_str(), (char *)0);
}else{
execl(strShell.c_str(), cmd.c_str(), "-c", strCmd.c_str(), (char *)0);
}
//printf("[Shell::Execute] child: execl: %s\n", strerror(errno));//转换错误码为对应的错误信息
_exit(127);
}
//parent
close(filedes[1]);
time_t btime = time(NULL);
char buf[10240 + 1] = {0};
while(true)
{
memset(buf,0,sizeof(buf));
int len = read(filedes[0], buf, sizeof(buf)-1);
//printf("[Shell::Execute] len =================: %d\n",len);
if (len < 0)
{
if (time(NULL) - btime < nTimeout)
{
usleep(1000);
continue;
}
//printf("[Shell::Execute] parent: kill child pid = %d for timeout %d s\n",pid,nTimeout);
char cmd[100] = {0};
sprintf(cmd,"kill -9 %d",pid);
system(cmd);
len = 0;
nRe = 1;
}
//recv finish or timeout -> break
if(len == 0)
{
if(waitpid(pid, NULL, WNOHANG) == 0)
{
continue;
}
//printf("[Shell::Execute] parent: child pid = %d exit\n",pid);
break;
}
//printf("[Shell::Execute] parent: %s\n",buf);
strRet += buf;
}
close(filedes[0]);
return nRe;
}
int Shell::ExecuteExit(const string& strCmd,string& strRet, const int nTimeout,bool& bExit,const string strShell)
{
if(strCmd.empty())
return -1;
//signal(SIGCHLD,SIG_IGN);
string cmd = strShell;
std::string::size_type pos = strShell.find_last_of('/');
if(pos != std::string::npos){
cmd = strShell.substr(pos+1);
}
//create pid
int filedes[2];
if(pipe(filedes) < 0)
{
//printf("[Shell::Execute] pipe create error\n");
return -1;
}
//设置为非阻塞
fcntl(filedes[0], F_SETFL, O_NONBLOCK);
//fcntl(filedes[1], F_SETFL, O_NONBLOCK);
int nRe = 0;
pid_t pid = fork();
if(pid < 0)
{
//printf("[Shell::Execute] fork error\n");
return -1;
}
//child
if(pid == 0)
{
//printf("child-----------my process id is %d\n",getpid());
close(filedes[0]);
if (filedes[1] != STDOUT_FILENO)
{
dup2(filedes[1], STDOUT_FILENO);//复制文件句柄用法
dup2(filedes[1], STDERR_FILENO);
close(filedes[1]);
}
if(cmd == "perl"){
execl(strShell.c_str(), cmd.c_str(), "-e", strCmd.c_str(), (char *)0);
}else{
execl(strShell.c_str(), cmd.c_str(), "-c", strCmd.c_str(), (char *)0);
}
//printf("[Shell::Execute] child: execl: %s\n", strerror(errno));//转换错误码为对应的错误信息
_exit(127);
}
//parent
close(filedes[1]);
time_t btime = time(NULL);
char buf[10240 + 1] = {0};
while(true)
{
memset(buf,0,sizeof(buf));
int len = read(filedes[0], buf, sizeof(buf)-1);
//printf("[Shell::Execute] len =================: %d\n",len);
if (len < 0)
{
if (time(NULL) - btime < nTimeout && !bExit)
{
usleep(1000);
continue;
}
//printf("[Shell::Execute] parent: kill child pid = %d for timeout %d s\n",pid,nTimeout);
char cmd[100] = {0};
sprintf(cmd,"kill -9 %d",pid);
system(cmd);
len = 0;
nRe = 1;
}
//recv finish or timeout -> break
if(len == 0)
{
if(waitpid(pid, NULL, WNOHANG) == 0)
{
continue;
}
//printf("[Shell::Execute] parent: child pid = %d exit\n",pid);
break;
}
//printf("[Shell::Execute] parent: %s\n",buf);
strRet += buf;
}
close(filedes[0]);
return nRe;
}
原文链接: https://www.cnblogs.com/wcc331902579/p/5912892.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/241273
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!