linux popen()与system()的区别
linux popen()与system()的区别
popen() 可以在调用程序和POSIX shell /usr/bin/sh 要执行的命令之间创建一个管道(请参阅sh-posix(1) )。
popen() 的参数是指向以空字符结尾的字符串的指针,这些字符串分别包含一个shell 命令行和一个I/O 模式,此
模式可以是进行读取的r ,或进行写入的w 。
popen() 可返回一个流指针,这样,当I/O 模式为w 时,便可以通过写入文件stream 来写入到命令的标准输入;
当I/O 模式为r 时,通过从文件stream 读取数据,从命令的标准输出读取数据。
popen() 打开的流应由pclose() 关闭,这需要等待终止关联的进程,然后返回命令的退出状态。
因为打开的文件是共享的,所以类型为r 的命令可用作输入过滤器,类型为w 的命令可用作输出过滤器。
system() 可执行由command 指向的字符串指定的命令。已执行命令的环境就如同使用fork() (请参阅fork(2) )
创建了一个子进程,子进程按以下方式通过调用execl() (请参阅exec(2) )来调用sh-posix(1) 实用程序:
execl("/usr/bin/sh", "sh", "-c", command, 0);
system() 在等待命令终止时将忽略SIGINT 和SIGQUIT 信号,同时阻塞SIGCHLD 信号。如果这会导致应用程
序错过一个终止它的信号,则应用程序应检查system() 的返回值;如果由于收到某个信号而终止了命令,应用程
序应采取一切适当的措施。
system() 不影响除自己创建的一个或多个进程以外的调用进程的任何子进程的终止状态。
在子进程终止之前, system() 不会返回。
-------------以上来自:https://www.cnblogs.com/lvzaina/archive/2013/02/22/2922858.html
--------------------------
暂时目前同事遇到的问题的是A 监控的一个端口,之后system了一条命令,这条命令去拉去指定位置的批量信息,而且可能会多次运行这条命令(有很多个拉取地址),但是可能在一次拉取过程中,传参或者非法地址等出错了,系统精灵。在重启的时候,获取不到指定的端口,造成错误;
解决的初步思路(未验证);
1,用popen替代system函数;
2,使用 fcntl(fd, F_SETFD, FD_CLOEXEC); 这种操作;
3,在在子进程运行开始处,把父进程的socket描述符close掉。子进程里边做popen之前,遍历下/proc/self/fd下的所有fd,给除了0,1,2以外的其他fd设置下FD_CLOEXEC,之后再调用下边的popen命令(这个可能会出问题,太粗暴);
4,遍历的时候分析下描述符对应的软连接是不是指向一个socket,以免错杀无辜的描述符。 给一个参考链接:http://blog.chinaunix.net/uid-317451-id-92698.html