Я бы подумал, что это будет проблема, с которой многие сталкивались раньше, но мне было трудно найти кого-нибудь, говорящего о проблемах «убить родителя».
Сначала я думал, что вы сможете сделать это с помощью (не совсем так, но вроде) простого вызова 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
.
Если это не работает (и вы не можете понять, как сделать что-то подобное), вы можете использовать обычный вызов clone вместе с вызовами setjump
и longjmp
для его эмуляции, или вы можете обойти потребность в семантике «возврата дважды» fork
и vfork
.
person
nategoose
schedule
08.10.2010