1

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

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

其中 filename 在这种情况下是"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?

谢谢你的帮助!

4

2 回答 2

1

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

正如评论中提到的,标准的第 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用于参数列表。

于 2012-09-16T23:19:00.710 回答
1
execve(argv[1], argv+1, envp);
于 2012-09-17T00:13:03.957 回答