我有一个TCP服务器应用程序,偶尔需要通过关闭绑定端口然后在以后打开它们来重新配置绑定端口。
该应用程序还需要执行与其通信的外部二进制文件。当前,这是使用popen()调用完成的。外部二进制运行时间可以跨越需要重新配置网络端口的时间。
问题是,当主应用程序关闭端口时,它由popen创建的用于运行二进制文件的“派生”进程接管。
这是有道理的(在tcp服务器在执行接受之前绑定和分叉时发生了什么?哪个进程将处理客户端请求?)中对此进行了讨论,但这是不希望的,因为主应用程序随后无法重新打开端口。
是否可以在这里使用popen(3)中可用的FD_CLOEXEC O_CLOEXEC?应用程序需要popen(3)提供的管道作为执行的二进制文件的stdin,是在CLOEXEC关闭其他文件时保持打开的文件句柄。
有没有更好的方法来运行二进制文件,而不会导致分支进程保留在封闭端口上?
在不继承句柄的情况下如何派生进程还有另一个可能相关的问题?
不,你不能启动其他程序,并从中取回无叉(2)其次是一些的execve(2)代码(这是什么popen
,posix_spawn
和system
正在做的)。你会更好地避免popen
或system
与代码pipe
+ fork
+execve
明确自己(因为你知道哪些文件描述符应保持并以接近(2) ,一般后fork
和之前的execve
子进程......),看到这个。
(除+一些热插拔功能外,每个进程和程序/sbin/init
都以fork
+开头execve
;并且您的外壳对于大多数命令(诸如内置命令除外)始终使用fork
+ )execve
cd
阅读一些不错的书,例如可在此处免费在线获取的Advanced Linux Programming书。另请参见syscalls(2)。使用(至少用于调试和了解事物)strace(1)和调试器()。研究源代码并在你的自由软件的libc(GNU libc中或MUSL-libc的),和你的shell的源代码。gdb
popen
system
你可以几乎模仿的execve(2)通过一个棘手的序列的mmap(2) (及相关的munmap
)电话,但并不完全(在近距离上的exec等..特别WRT)。您可能还需要调用过时的setcontext(3)(或编写等效的汇编代码)。
您可能考虑与执行类似fork
&的类似外壳程序的专用服务器程序通信execve
(有关示例和灵感,请参阅我的execicar.c)。也许您会发现daemon(3)有用。
更好的选择可能是在您的应用程序中嵌入一些解释器(例如lua或guile)和/或dlopen(3)一些插件。缺点是(解释的脚本或插件中的)错误会影响整个服务器。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句