我需要从服务器派生一个exec。由于我的服务器内存占用量很大,我打算使用vfork()
/ linux clone()
。我还需要为stdin
/ stdout
/ stderr
打开管道。这是clone()
/ vfork()
允许的吗?
答案 0 :(得分:2)
来自标准:
[..]如果由
vfork()
创建的进程修改除用于存储来自pid_t
的返回值的类型vfork()
的变量之外的任何数据,则行为未定义,或者从调用vfork()
的函数返回,或在成功调用_exit()
或其中一个exec
函数系列之前调用任何其他函数。
调用setuid
或pipe
等函数的问题在于它们可能影响父进程和子进程之间共享的地址空间中的内存。如果你需要在exec
之前做任何事情,最好的方法是编写一个小的填充程序来完成你需要的任何事情然后exec
到最终的子进程(也许通过{{提供的参数) 1}})。
argv
答案 1 :(得分:1)
我使用clone()
代替,使用CLONE_VFORK|CLONE_VM
标志;有关详细信息,请参阅man 2 clone。
由于未设置CLONE_FILES
,子进程有自己的文件描述符,可以关闭和打开标准描述符,而不会影响父进程。
由于克隆过程是一个单独的过程,因此它有自己的用户和组ID,因此请通过setresgid()
和setresuid()
设置它们(可能会调用setgroups()
或initgroups()
首先设置其他群组(请参阅man 2 setresuid,man 2 setgroups和man 3 initgroups了解详情)不会影响家长。
CLONE_VFORK|CLONE_VM
标志意味着此clone()
应该像vfork()
一样,子进程与父进程在同一内存空间中运行直到execve()
调用。
这种方法避免了使用中间可执行文件时的延迟 - 这非常重要 - 但这种方法完全取决于Linux。