我可以在没有fork的情况下执行shell或系统调用吗?

rol*_*ger 2 c linux multithreading fork tcp

我有一个TCP服务器应用程序偶尔需要通过关闭它们然后稍后打开它们来重新配置绑定端口.

应用程序还需要执行与之通信的外部二进制文件.目前使用popen()调用完成此操作.外部二进制运行时间可以跨越需要​​重新配置网络端口的时间段.

问题是,当主应用程序关闭一个端口时,它由popen为运行二进制文件创建的'forked'进程接管.

这是有意义的(讨论在tcp服务器在接受之前绑定和分叉时会发生什么?哪个进程会处理客户端请求?),但这是不可取的,因为主应用程序无法重新打开端口.

是否可以使用popen(3)中可用的FD_CLOEXEC O_CLOEXEC?应用程序需要popen(3)提供的管道作为stdin到执行的二进制文件,当CLOEXEC关闭其他文件时,文件句柄保持打开状态.

有没有更好的方法来运行二进制文件,这不会导致分支进程保持一个封闭的端口?

在没有继承句柄的情况下如何分叉进程还有另一个可能相关的问题?

Bas*_*tch 5

不,你不能启动其他程序,并从它那里得到回不叉(2)其次是一些的execve(2)代码(这是什么popen,posix_spawn和system正在做的).你最好自己明确地避免popen或system编写pipe+ fork+ execve(因为你知道应该保留哪些文件描述符以及要关闭哪些文件描述符(2),通常在子进程fork之前和之后execve...),请参阅此内容.

(每个进程和程序,除了/sbin/init一些hotplug之外的东西,都是以fork+ 开头的execve;而你的shell经常使用fork+ execve来处理大多数命令,除了内置的那些命令cd)

所述叉(2)呼叫可以通过实现克隆(2) .

阅读一些好的书,如高级Linux编程书,这里免费在线提供.另见syscalls(2).使用(至少用于调试和理解事物)strace(1)和调试器(gdb).研究源代码popen并system在你的自由软件的libc(GNU libc中或MUSL-libc的),和你的shell的源代码.

你可以几乎模仿的execve(2)通过一个棘手的序列的mmap(2) (以及相关的munmap)调用,但并不完全(在近距离上的exec等..特别WRT).您可能还需要调用过时的setcontext(3)(或编写等效的汇编程序代码).

你可能会考虑用专门的壳状类似服务器的程序做沟通fork和execve(见我execicar.c例如和灵感).也许你会发现守护进程(3)很有用.

一个更好的选择可能是在你的应用程序中嵌入一​​些解​​释器(如lua或guile)和/或dlopen(3)一些插件.缺点是错误(在解释的脚本或插件中)会影响整个服务器.

  • 自己编码`pipe` +`fork` +`execve`,并适当调用`close` (3认同)
  • @ PeterA.Schneider,Windows与众不同.它根本不知道fork().*Nix全是fork,Win*没有fork - 而是他们有CreateProcessEx.我更喜欢叉子. (2认同)