【问题标题】:Starting program using execv and passing arguments with out raising argc使用 execv 启动程序并在不引发 argc 的情况下传递参数
【发布时间】:2019-06-11 01:04:40
【问题描述】:

我在课堂上得到了这个代码:

    int main(int argc, char **argv)
    {
        if(argc)
        {
            return 1;
        }

        puts(argv[3]);
        return 0;
    }

现在,我应该编写第二个程序来执行它并让它打印“Hello World!”。所以我必须找到一种方法来传递参数(我假设使用 execv)同时让 argc 保持在 0。

这是我目前所拥有的:

int main()
{
    pid_t pid = fork();

    if(pid == 0)
    {
        char *argv[] = { "filepath", "placeholder",
                            "placeholder", "Hello World!" };
        execv("filepath", argv);
        exit(0);
    }
    else
    {
        waitpid(pid, 0, 0);
    }
    
    return 0;
}

这将在 Linux 上运行。

我尝试了 mbj 的原始建议,在参数数组中传递一个 0,遗憾的是没有奏效。但是,如果我将 0 作为第一个参数,则 argc 变为 0,但是在尝试打印参数时会得到输出“LC_MEASUREMENT=de_DE.UTF-8”。谷歌搜索这也没有真正帮助我。

我在这里完全不知所措,因此感谢您提供任何帮助。

【问题讨论】:

  • 这将在什么操作系统上运行?
  • 在 Linux 上,将其添加到帖子中

标签: c arguments fork argc


【解决方案1】:

好的,经过我自己的一些实验,我现在想通了。

由于将一个以NULL0)开头的数组传递给execv导致程序打印出LC_MEASUREMENT=de_DE.UTF-8,我意识到这一定意味着argv[3]指的是进程中的一个元素环境(LC_MEASUREMENT 是用于在 Linux 中配置区域设置的环境变量之一)。

execv 的解决方案

由于execv 会将当前环境复制到新程序中,我们只需修改环境并将字符串"Hello World!" 放在正确的位置,然后再调用execv。事实证明,被打印的字符串是环境索引 2 所指向的字符串。

要访问当前环境,我们需要在main之外声明environ变量:

external char **environ;

int main() 
{
    ...

然后在调用execv之前执行此操作:

        char *argv[] = { NULL };
        environ[2] = "Hello world!";
        execv("filepath", argv);

execve 更简单的解决方案

我们可以使用execve 函数,而不是在调用execv 之前声明external char **environ 并修改当前环境,它允许我们传入一个新的字符串数组以用作程序的环境:

        char *argv[] = { NULL };
        char *envp[] = { "foo", "bar", "Hello World!", NULL };
        execve("filepath", argv, envp);

如上面的代码 sn-p 所示,无论我们使用哪种方法,"Hello World!" 都需要位于环境的索引 2

工作原理

这样做的原因是,当程序执行时,命令行参数和环境如何在进程内存中布局有一个标准:字符指针的环境数组放置在命令行参数数组之后。

由于这些数组以 NULL 条目终止,因此将如下所示:

+---------+---------------------------------------+ 
| Args    | Environment                           |
+---------+---------+---------+---------+---------+
|  NULL   | envp[0] | envp[1] | envp[2] |  NULL   | 
+---------+---------+---------+---------+---------+
    ^         ^                   ^                     
    |         |                   |
 argv[0]    argv[1]     ...     argv[3]

我希望 ASCII 艺术可以帮助您理解为什么当我们执行这样的程序时,argv[3]environ[2] 的含义相同。

【讨论】:

  • 谢谢,这个解决方案有效!也感谢您的精彩解释,使其非常容易理解。
猜你喜欢
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
  • 2010-09-27
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 2022-12-23
  • 2023-03-19
相关资源
最近更新 更多