1、FILE* popen(const char* cmd,const char* type);
int pclose(FILE* stream);
popen() 函数 fork() 一个子进程,创建管道用于父子进程间通信,父进程要么从管道读,要么往管道写,执行一个 shell 以运行命令来开启一个进程
相比于 system() 的又是在于使用简单,popen() 只返回两个值,成功返回子进程的 status,失败返回 - 1
2、int system(const char* cmd);
处理了 fork()、execl()、waitpid() 这些细节,还有一些信号
1、这个库函数使用 fork() 创建一个子进程来;
2、子进程调用 / bin/sh-c cmd 执行指定的参数命令 (/bin/sh 一般是一个软连接,指向某个具体的 shell, 比如 bash,-c 选项告诉 shell 从字符串 cmd 中读取命令), 执行完之后返回调用原进程;
3、父进程调用 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
《完》
来源: http://www.bubuko.com/infodetail-2224882.html