POSIX:你如何确定自己的进程的文件图像,这样你就可以自己执行?

时间:2013-11-14 05:15:06

标签: c linux exec posix fork

如何确定代表当前进程'可执行文件的文件?

问题是argv[0]不可靠,好像它是通过execXp调用的,满足非限定命令的路径条目可能会或可能不会被预先添加。此外,exec*的任何来电者都可以用任何内容替换argv[0]

因此,如果您运行ps,则无法保证argv[0]"/usr/bin/ps"。事实上,你可能保证了OPPOSITE。

我需要以下其中一项:

  1. 完整路径名(不自行进行路径搜索,以免我使用的envp不是shell使用的那个)
  2. 实时预打开文件描述符到与当前进程'image
  3. 对应的文件
  4. 一些魔术描述符,对应于当前在内存中的代码段(虽然不太确定BSS段)
  5. 通过这种方式,在启动时我可以快速打开FD到我自己的可执行文件(对于案例1,如果文件被删除并变得不可打开),然后在更晚的日期调用:

    int fexecve(int fd, char *const argv[], char *const envp[]);
    
    自己

    fork / exec(通常在OS-X上需要解决fork()之后全局和系统描述符状态的不可靠性)。换句话说(这个例子当然很愚蠢):

    void magicallyReplicate(argc, argv)
    {
      if (!fork()) {
        magicallyExecMyself(argc, argv);
      }
    }
    

    甚至只是:

    void startOver(argc, argv)
    {
      magicallyExecMyself(argc, argv);
    }
    

    当然,在我的示例中,我将使用不同的argv,以便我可以以不同的模式运行。

    (早期“否”反驳:你不能使用clone(),因为它属于fork()的血统。

1 个答案:

答案 0 :(得分:2)

所以基本上,最简单的平台就是MacOS(因为在forkexec之间调用时,libc完全坏了,像getaddrinfo segfault这样简单的东西) - 在Darwin上,内核给你带来了在盘子上启动过程时的完整二进制名称。使用main(http://unixjunkie.blogspot.co.uk/2006/02/char-apple-argument-vector.html)的第四个参数或与_NSGetExecutablePath完全相同的方式检索它 - 它只是一个知道内核放置文件名的相同特殊位置的函数。

对于所有平台,这是一个个案的问题。此主题中的完整详细信息:Finding current executable's path without /proc/self/exe