我有一个SIP服务器的示例应用程序监听tcp和udp端口5060.
在代码的某个时候,我做一个系统(“pppd文件/ etc / ppp / myoptions&”);
在代码的某个时候,我做一个系统(“pppd文件/ etc / ppp / myoptions&”);
之后,如果我做一个netstat -apn,它显示我的端口5060也为pppd打开!
有什么办法可以避免吗?这是Linux中系统功能的标准行为吗?
谢谢,
Elison
解决方法
是的,默认情况下,当您分配进程(哪个系统)时,子进程继承所有父进程的文件描述符.如果孩子不需要这些描述符,它应该关闭它们.使用系统(或任何其他执行fork exec的方法)执行此操作的方法是将FD_CLOEXEC标志设置为不能由您的子进程使用的所有文件描述符.每当任何一个小孩执行其他程序时,这将导致它们自动关闭.
一般来说,任何时候,你的程序都会打开任何一段文件描述符,这个文件描述符会持续一段时间(例如你的例子中的一个监听套接字),不应该与孩子共享,你应该
fcntl(fd,F_SETFD,fcntl(fd,F_GETFD) | FD_CLOEXEC);
在文件描述符上.
截至2016年修改POSIX.1,您可以在创建套接字时使用SOCK_CLOEXEC标志或“套接字”类型自动获取此行为:
listenfd = socket(AF_INET,SOCK_STREAM|SOCK_CLOEXEC,0); bind(listenfd,... listen(listemfd,...
即使某些其他同时运行的线程执行系统或fork exec调用,它将被正确关闭.幸运的是,这个标志已经在Linux和BSD unixes上支持了一段时间(但不幸的是OSX).