我本以为这将是许多其他人以前遇到的问题类型,但我很难找到任何人谈论“杀死父母”问题。
我最初认为您应该能够通过(不完全如此,但有点)简单的调用来做到这一点clone
,就像这样:
pid_t new_vfork(void) {
return clone(child_func, /* child function */
child_stack, /* child stack */
SIGCHLD | CLONE_VM, /* flags */
NULL, /* argument to child */
NULL, /* pid of the child */
NULL, /* thread local storage for child */
NULL); /* thread id of child in child's mem */
}
除了确定 child_stack 和 child_func 以使用 vfork 的方式工作非常困难,因为 child_func 需要是克隆调用的返回地址,而 child_stack 需要是堆栈的顶部进行实际的系统调用(sys_clone)。
您可能会尝试sys_clone
直接致电
pid_t new_vfork(void) {
return sys_clone( SIGCHLD | CLONE_VM, NULL);
}
我认为这可能会得到你想要的。传递 NULL 作为第二个参数,即 child_stack 指针,会导致内核执行与 vfork 和 fork 中相同的操作,即使用与父级相同的堆栈。
我从来没有sys_clone
直接使用过,也没有测试过,但我认为它应该可以工作。我相信:
sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);
相当于vfork
。
如果这不起作用(并且您无法弄清楚如何做类似的事情),那么您可以使用常规克隆调用以及setjump
调用longjmp
来模拟它,或者您可以绕过需要fork
和的“返回两次”语义vfork
。