linux 关闭popen 打开的命令
2016-08-05 21:06
507 查看
程序设计了一个图形界面用于开了一个线程执行终端命令,通过pope打开一个管道来执行命令,
此时需要循环读取程序执行的结果。
void* command_exec(void* cmdstr)
{
FILE *cmdStream=NULL;
char *cmd = (char *)cmdstr;
char buff[200];
if(NULL==(cmdStream=popen(cmd,"r")))
{
fprintf(stderr,"execute command failed: %s",strerror(errno));
pthread_exit(NULL);
}
while(fgets(buff,200, cmdStream)!=NULL)
{
g_printf("%s\n", buff);
}
pclose(cmdStream);
pthread_exit(NULL);
}
由于命令一直都在执行,一直在while循环中 , 该线程不能结束,此时需要结束命令,通过pthread_kill结束线程来实现发现命令所起的进程并没有关闭,而且cmdSream文件流也没有正常close, 最后通过信号处理函数
void command_exit() {
if(cmdStream != NULL) {
pclose2(cmdStream);
cmdStream = NULL;
pthread_exit((void *)2);
}
}
关闭了管道,但是命令进程还是存在着,最后通过修改popen , pclose 函数源码自己实现结束进程来完成。
修改后的函数如下,在pclose 中添加了kill
#define SHELL "/bin/bash"
static pid_t *childpid=NULL; /*ptr to array allocated at run-time*/
static int maxfd; /*from our open_max(), {Prox openmax}*/
FILE *popen2(const char *cmdstring, const char *type)
{
int i, pfd[2];
pid_t pid;
FILE *fp;
/*only allow "r" or "w"*/
if(type[0] != 'r' && type[0]!='w' || type[1] != 0) {
errno=EINVAL;
return (NULL);
}
if(childpid == NULL) { /*first time throngh, allocate zeroed out array for child pids*/
maxfd = sysconf(_SC_OPEN_MAX);
if((childpid = calloc(maxfd, sizeof(pid_t))) == NULL)
return(NULL);
}
if(pipe(pfd) < 0)
return(NULL); //errno set by pipe()
if((pid = fork()) < 0)
return(NULL); //error set by fork()
else if(pid==0) { /*child*/
if(*type == 'r') {
close(pfd[0]);
if(pfd[1] != STDOUT_FILENO) {
dup2(pfd[1], STDOUT_FILENO);
close(pfd[1]);
}
} else {
close(pfd[1]);
if(pfd[0] != STDIN_FILENO) {
dup2(pfd[0], STDIN_FILENO);
close(pfd[0]);
}
}
/*close all descriptiors in childpid*/
for(i = 0; i < maxfd; i++)
if(childpid[i] > 0)
close(i);
execl(SHELL, "bash", "-c", cmdstring, (char *)0);
_exit(127);
}
/*parent*/
if(*type == 'r') {
close(pfd[1]);
if((fp = fdopen(pfd[0], type)) == NULL)
return (NULL);
}else {
close(pfd[0]);
if((fp = fdopen(pfd[1], type)) == NULL)
return (NULL);
}
childpid[fileno(fp)] = pid; /*remember child pid for this fd*/
return(fp);
}
int pclose2(FILE *fp)
{
int fd, stat;
pid_t pid;
printf("hello>>>>>>>>>>>>>\n");
if(childpid == NULL) /*popen() has never benn called*/
return (-1);
fd = fileno(fp);
if((pid = childpid[fd]) == 0)
return (-1); //fp wasn't opened by popen()
childpid[fd] = 0;
if(fclose(fp) == EOF)
return (-1);
if( kill(pid, SIGKILL) != 0) {
printf("kill failed\n");
perror("kill");
}
else {
printf("%d killed\n", pid);
}
while(waitpid(pid, &stat, 0) < 0) {
if(errno != EINTR )
return (-1); /*error other than EINTR from waitpid()*/
}
return(stat);
}
解决了问题、保持在图形界面上只执行一个命令进程并显示命令结果
此时需要循环读取程序执行的结果。
void* command_exec(void* cmdstr)
{
FILE *cmdStream=NULL;
char *cmd = (char *)cmdstr;
char buff[200];
if(NULL==(cmdStream=popen(cmd,"r")))
{
fprintf(stderr,"execute command failed: %s",strerror(errno));
pthread_exit(NULL);
}
while(fgets(buff,200, cmdStream)!=NULL)
{
g_printf("%s\n", buff);
}
pclose(cmdStream);
pthread_exit(NULL);
}
由于命令一直都在执行,一直在while循环中 , 该线程不能结束,此时需要结束命令,通过pthread_kill结束线程来实现发现命令所起的进程并没有关闭,而且cmdSream文件流也没有正常close, 最后通过信号处理函数
void command_exit() {
if(cmdStream != NULL) {
pclose2(cmdStream);
cmdStream = NULL;
pthread_exit((void *)2);
}
}
关闭了管道,但是命令进程还是存在着,最后通过修改popen , pclose 函数源码自己实现结束进程来完成。
修改后的函数如下,在pclose 中添加了kill
#define SHELL "/bin/bash"
static pid_t *childpid=NULL; /*ptr to array allocated at run-time*/
static int maxfd; /*from our open_max(), {Prox openmax}*/
FILE *popen2(const char *cmdstring, const char *type)
{
int i, pfd[2];
pid_t pid;
FILE *fp;
/*only allow "r" or "w"*/
if(type[0] != 'r' && type[0]!='w' || type[1] != 0) {
errno=EINVAL;
return (NULL);
}
if(childpid == NULL) { /*first time throngh, allocate zeroed out array for child pids*/
maxfd = sysconf(_SC_OPEN_MAX);
if((childpid = calloc(maxfd, sizeof(pid_t))) == NULL)
return(NULL);
}
if(pipe(pfd) < 0)
return(NULL); //errno set by pipe()
if((pid = fork()) < 0)
return(NULL); //error set by fork()
else if(pid==0) { /*child*/
if(*type == 'r') {
close(pfd[0]);
if(pfd[1] != STDOUT_FILENO) {
dup2(pfd[1], STDOUT_FILENO);
close(pfd[1]);
}
} else {
close(pfd[1]);
if(pfd[0] != STDIN_FILENO) {
dup2(pfd[0], STDIN_FILENO);
close(pfd[0]);
}
}
/*close all descriptiors in childpid*/
for(i = 0; i < maxfd; i++)
if(childpid[i] > 0)
close(i);
execl(SHELL, "bash", "-c", cmdstring, (char *)0);
_exit(127);
}
/*parent*/
if(*type == 'r') {
close(pfd[1]);
if((fp = fdopen(pfd[0], type)) == NULL)
return (NULL);
}else {
close(pfd[0]);
if((fp = fdopen(pfd[1], type)) == NULL)
return (NULL);
}
childpid[fileno(fp)] = pid; /*remember child pid for this fd*/
return(fp);
}
int pclose2(FILE *fp)
{
int fd, stat;
pid_t pid;
printf("hello>>>>>>>>>>>>>\n");
if(childpid == NULL) /*popen() has never benn called*/
return (-1);
fd = fileno(fp);
if((pid = childpid[fd]) == 0)
return (-1); //fp wasn't opened by popen()
childpid[fd] = 0;
if(fclose(fp) == EOF)
return (-1);
if( kill(pid, SIGKILL) != 0) {
printf("kill failed\n");
perror("kill");
}
else {
printf("%d killed\n", pid);
}
while(waitpid(pid, &stat, 0) < 0) {
if(errno != EINTR )
return (-1); /*error other than EINTR from waitpid()*/
}
return(stat);
}
解决了问题、保持在图形界面上只执行一个命令进程并显示命令结果
相关文章推荐
- linux下打开、关闭tomcat,实时查看tomcat运行日志,等一些命令
- linux下打开关闭端口命令
- Linux中chkconfig命令打开或关闭系统服务的使用教程
- linux终端下为什么用命令打开软件后,要关闭软件才能继续下一条命令?
- 如何在 Linux/Unix 的 Bash 中打开或关闭 ls 命令颜色显示 | Linux 中国
- linux下打开关闭端口命令
- linux下打开关闭端口命令
- linux下打开关闭端口命令
- Linux打开、关闭防火墙,打开某端口的命令
- Linux 打开/关闭CPU命令
- SELinux是什么意思,如何关闭?Linux下的防火墙用什么命令打开?
- linux 防火墙的打开和关闭命令
- linux打开和关闭光驱的命令
- Linux下关闭和开启防火墙命令
- 打开WORD出现“对话框打开时命令无法执行 单击 确定 关闭对话框以继续”的故障
- Linux下关闭和开启防火墙命令
- 开启和关闭LINUX 放火墙的命令
- Linux下用命令关闭显示器
- VC菜单命令详解(文件打开、保存与关闭)
- Entity Framework中出现"已有打开的与此命令相关联的 DataReader,必须首先将它关闭。"的解决方案