سؤال

I'm working on a project that basically does the same thing as strace(1) using ptrace(). Basically we have a controller.c program that takes an executable as an argument and it outputs any system calls made by the executable (for example % controller ls -l) We are using the execve() to run the executable file, but we are having a little bit of trouble. execve takes the following arguments

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

where filename in this instance would be "ls", and argv[] is a list of the arguments for the given file name. So we have something that looks like this (in the C file)

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 
  }
}

So if we get an executable, for example controller ls -l, where argv[0] = "controller", argv[1] = "ls", and argv[2] = "-l", how can we pass the correct parameter at "ARGUMENT LIST" (where the arguments in this case is just "-l" but it could be more)?

Basically, how do we initialize an array of type const char * such that the array has the argument values for the executable? Do we even need to worry about having extra values in the array and just past argv for ARGUMENT LIST?

Thanks for your help!

هل كانت مفيدة؟

المحلول

You can simply pass argv + 1 (to skip your program's name). argv + 1 is a pointer to an array starting from the second element of argv, which is the executed program's name. argv + 1 is equivalent to &argv[1], and you can use whatever style you prefer.

As mentioned in the comments, section 5.1.2.2.1 of the standard specified that argv is indeed null-terminated. The section below is retained for completeness.

In case C doesn't guarantee argv is null-terminated (and it's not clear to me whether it does or not), you can do:

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

and use new_argv for the argument list.

نصائح أخرى

execve(argv[1], argv+1, envp);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top