在Linux上实现posix_spawn

Gro*_*uez 4 c linux posix

我很想知道是否可以使用+ 的组合在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)

有任何想法吗?

R..*_*R.. 9

正如其他人在评论中指出的那样,posix_spawn允许创建一个由于执行失败或其他后叉失败而立即死亡的子进程; 调用应用程序需要为此做好准备.但当然最好不要这样做.

在这个问题上写的答案中描述了 exec故障传递给父母的一般过程:什么可能导致exec失败?接下来发生什么?.

不幸的是,vfork由于其令人讨厌的返回 - 两次语义,您需要执行的某些操作不合法.我过去在ewontfix.com上的一篇文章中介绍了这个主题.用于posix_spawn避免复制VM 的解决方案似乎cloneCLONE_VM(并且可能CLONE_VFORK)一起使用以获得共享内存但不在同一堆栈上运行的新进程.但是,这仍然需要非常小心,以避免对可能修改父级使用的内存的libc函数进行任何调用.我目前的实现在这里:

http://git.musl-libc.org/cgit/musl/tree/src/process/posix_spawn.c?id=v1.1.4

你可以看到它相当复杂.阅读git历史记录可能会提供有关某些设计决策的信息.