我很想知道是否可以使用+ 的组合在Linux中实现posix_spawn.以非常简单的方式(省略大多数可选参数),这可能看起来或多或少像这样:vforkexec
int my_posix_spawn(pid_t *ppid, char **argv, char **env)
{
pid_t pid;
pid = vfork();
if (pid == -1)
return errno;
if (pid == 0)
{
/* Child */
execve(argv[0], argv, env);
/* If we got here, execve failed. How to communicate this to
* the parent? */
_exit(-1);
}
/* Parent */
if (ppid != NULL)
*ppid = pid;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道如何处理vfork成功的情况(因此创建子进程)但exec调用失败.似乎没有办法将此信息传达给父母,这只会看到它显然可以成功创建子进程(因为它会获得有效的pid)
有任何想法吗?
正如其他人在评论中指出的那样,posix_spawn允许创建一个由于执行失败或其他后叉失败而立即死亡的子进程; 调用应用程序需要为此做好准备.但当然最好不要这样做.
我在这个问题上写的答案中描述了将 exec故障传递给父母的一般过程:什么可能导致exec失败?接下来发生什么?.
不幸的是,vfork由于其令人讨厌的返回 - 两次语义,您需要执行的某些操作不合法.我过去在ewontfix.com上的一篇文章中介绍了这个主题.用于posix_spawn避免复制VM 的解决方案似乎clone与CLONE_VM(并且可能CLONE_VFORK)一起使用以获得共享内存但不在同一堆栈上运行的新进程.但是,这仍然需要非常小心,以避免对可能修改父级使用的内存的libc函数进行任何调用.我目前的实现在这里:
http://git.musl-libc.org/cgit/musl/tree/src/process/posix_spawn.c?id=v1.1.4
你可以看到它相当复杂.阅读git历史记录可能会提供有关某些设计决策的信息.