Я бы подумал, что это будет проблема, с которой сталкивались многие другие, но мне было трудно найти кого-нибудь, кто бы говорил о проблемах "убить родителя".
IПервоначально считалось, что вы должны сделать это с помощью (не совсем, но вроде) простого вызова 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
.