【问题标题】:C and execve(3) argumentsC 和 execve(3) 参数
【发布时间】:2012-09-16 23:12:25
【问题描述】:

我正在做一个与strace(1) 基本相同的项目,使用ptrace()。基本上我们有一个controller.c 程序,它接受一个可执行文件作为参数,并输出可执行文件所做的任何系统调用(例如% controller ls -l) 我们正在使用execve() 来运行可执行文件,但我们遇到了一些麻烦。 execve 接受以下参数

 execve( const char *filename, char *const argv[], char *const envp[] )

这里的文件名是"ls"argv[] 是给定文件名的参数列表。所以我们有一些看起来像这样的东西(在 C 文件中)

int main(int argc, char *argv[],char *envp[]){
  pid_t child;
  child = fork;

  if(/* CHILD */){
    ptrace(PTRACE_TRACEME,0, NULL, NULL);

    if(argc == 2) {
      execve(argv[1],NULL,envp);
    }
    else {
      execve( argv[1], /* ARGUMENT LIST */, envp);
    }

  } else /* PARENT */ {
    //PARENT CODE 
  }
}

所以如果我们得到一个可执行文件,例如controller ls -lwhere argv[0] = "controller"argv[1] = "ls"argv[2] = "-l",我们如何才能在“ARGUMENT LIST”中传递正确的参数(在这种情况下,参数只是"-l" 但可能更多)?

基本上,我们如何初始化const char * 类型的数组,以使该数组具有可执行文件的参数值?我们是否甚至需要担心数组中有额外的值并且刚刚超过 argv 的 ARGUMENT LIST?

感谢您的帮助!

【问题讨论】:

  • 我不太会使用 C。这种语法是否适用于获取某个数组的子数组? (我要试一试)
  • 首先,你根本不需要那个内部的if/else,其次,为什么不把&argv[1]作为execve的中间参数?
  • argv + n 只是一个指向 argv 的 nth 元素的数组/指针。相当于&argv[n]

标签: c exec constants ptrace execve


【解决方案1】:

您可以简单地传递argv + 1(跳过您的程序名称)。 argv + 1 是一个指向数组的指针,该数组从argv 的第二个元素开始,这是执行程序的名称。 argv + 1 相当于&argv[1],你可以使用任何你喜欢的样式。

如 cmets 中所述,标准的第 5.1.2.2.1 节指定 argv 确实是空终止的。为了完整起见,保留以下部分。

如果 C 不保证 argv 是空终止的(我不清楚它是否是),你可以这样做:

char **new_argv = malloc((argc-1) * sizeof(char*));
for (int i = 0; i < argc - 1) new_argv[i] = argv[i+1];

并使用new_argv 作为参数列表。

【讨论】:

  • 我想你会发现 C 确实保证 argv 和 envp 数组是空终止的。
  • @Neil - 你有没有在某处找到证据?我只是快速浏览了一下规范,但没有任何让我感到惊讶的东西。
  • @CarlNorum:this question 的答案提到标准的 5.1.2.2.1 指定 argv 是空终止的,这是我一直认为的。 envp 必须以 NULL 结尾,才能知道它的结束。
  • @AusCBloke,我现在正在看,我看到了这条线。我不知道我之前是怎么错过的——它正盯着我的脸:“argv[argc] 应该是一个空指针。”。 envp 并没有真正参与其中,因为它无论如何都不是标准的 C。
【解决方案2】:
execve(argv[1], argv+1, envp);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 2018-09-19
    相关资源
    最近更新 更多