これは他の多くの人が以前に遭遇したタイプの問題であると私は思っていたでしょうが、「親を殺す」問題について話している人を見つけるのに苦労しました.
私は当初、次のように (それほどではありませんが、一種の) への単純な呼び出しでこれを実行できるはずだと考えていました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);
}
あなたが望むものを手に入れることができると思います。child_stack ポインターである 2 番目の引数として NULL を渡すと、カーネルは vfork および fork と同じことを行い、親と同じスタックを使用します。
私はsys_clone
直接使用したことがなく、これをテストしていませんが、うまくいくはずです。私は信じている:
sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);
と同等vfork
です。
これが機能しない場合 (そして、似たようなことを行う方法がわからない場合) は、通常の clone 呼び出しをsetjump
andlongjmp
呼び出しと一緒に使用してエミュレートするか、必要性を回避できる可能性があります。fork
との「2 回戻る」セマンティクスvfork
。