一、FILE* popen(const char* cmd,const char* type);html
int pclose(FILE* stream);
shell
popen()函数fork()一个子进程,建立管道用于父子进程间通讯,父进程要么从管道读,要么往管道写,执行一个shell以运行命令来开启一个进程bash
相比于system()的又是在于使用简单,popen()只返回两个值,成功返回子进程的status,失败返回-1
ide
二、int system(const char* cmd);函数
处理了fork()、execl()、waitpid()这些细节,还有一些信号
htm
一、这个库函数使用fork()建立一个子进程来;blog
二、子进程调用/bin/sh-c cmd执行指定的参数命令(/bin/sh通常是一个软链接,指向某个具体的shell,好比bash,-c选项告诉shell从字符串cmd中读取命令),执行完以后返回调用原进程;
继承
三、父进程调用waitpid等待子进程结束。进程
执行命令时SIGCHLD将被阻塞,在调用system()的进程中SIGINT和SIGQUIT将被忽略。
字符串
返回值:
若是cmd是NULL,返回非0,通常为1;
若是fork()失败,即子进程没法被建立,返回-1;
若是shell在子进程中不能被替换,即execl()失败,返回127;
若是全部系统调用成功了,子进程执行cmd命令,但cmd命令不必定执行成功,返回cmd经过exit或return返回的值;
system()源码:
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()会继承环境变量,编写具备SUID/SGID权限的程序时不要用这个函数
建议system()只用来执行shell命令
建议监控一下system()函数执行完毕以后的errno值
建议使用popen()代替system()
http://blog.sina.com.cn/s/blog_8043547601017qk0.html
《完》