0

Good morning everyone! I am trying to create a fork/exec call from a parent program via a passed '-e' parameter (e.g. parent -e child key1=val1 ...). As a result I want to copy all the values after the first two in the argv array into a new array child_argv. Something like:

const char *child_argv[10];  // this is actually a global variable
static const char *sExecute;

      int I = 0;
const char *Value = argv[1];
    sExecute = Value;

      for (i=2; i<argc; i++) {
             child_argv[I] = argv[i];
             I++;
      }
    child_argv[I] = NULL;   // terminate the last array index with NULL

This way I can call the exec side via something like:

execl(sExecute, child_argv);

However I get the error message "error: cannot convert 'const char**' to 'const char*' for argument '2' to 'execl(const char*, const char*, ...)'". I have even tried to use an intermediate step:

const char *child_argv[10];  // this is actually a global variable
static const char *sExecute;

      int I = 0;
const char *Value = argv[1];
    sExecute = Value;

      for (i=2; i<argc; i++) {
    const char *Value = argv[i+1];
             child_argv[I] = Value;
             I++;
      }
    child_argv[I] = NULL;   // terminate the last array index with NULL

But I can't figure this out. Any help would be greatly appreciated!

UPDATE

As was pointed out, I should be using 'execv' instead of 'execl' in this situation. Still getting errors though...

UPDATE 2

I ended up copying the array without the desired parameters of argv. See the post here to see the result How to copy portions of an array into another array

Community
  • 1
  • 1
user1646428
  • 179
  • 2
  • 12
  • Your code doesn't include the `execl` call which is the source of the compile error. But like the error suggests, you are passing in `child_argv` (of type `const char**`) when it wants a `const char*`. – Barry Aug 26 '15 at 14:42
  • 2
    I recommend you read [the `execl` manual page](http://man7.org/linux/man-pages/man3/exec.3.html), and the reason for the error should be pretty obvious. Actually, if you *read the error message*, you would understand the reason as well. – Some programmer dude Aug 26 '15 at 14:43
  • @Barry the 'execl' call was included in the post. How can I be passing a const char** when child_argv was created as an array of const char*? – user1646428 Aug 26 '15 at 14:50

2 Answers2

2

From here: http://linux.die.net/man/3/exec

I think you mean to call "execv" not "execl". Execl seems to take a variable number of arguments, expecting each const char * to be another argument, while execv takes an array of arguments.

Chris Beck
  • 15,614
  • 4
  • 51
  • 87
  • Oppps, looking back over the reference material, you are right! I updated to use 'execv', but now I'm getting the error "error: invalid conversion from 'const char**' to 'char* const*' [-fpermissive]" – user1646428 Aug 26 '15 at 14:57
  • you might want to read this I guess, http://stackoverflow.com/questions/7914444/what-are-top-level-const-qualifiers, but it sounds like you need to change `const char *child_argv[10];` to `const char * const child_argv[10];` or something along these lines. – Chris Beck Aug 26 '15 at 15:01
  • @user the point is that execl expects to be passed an array of constant strings. when you make your type be `const char *child_argv[10]`, that is a constant array of non constant strings. so you need to make it an array of constant strings (in any number of ways) to make the warnings go away. – Chris Beck Aug 26 '15 at 15:09
  • @Beck I have tried several things but can't figure this out. C++ is not my programming language of choice... Any other thoughts? – user1646428 Aug 26 '15 at 15:28
  • Really you just need to follow link above and read the answer to that question very carefully. Or, post a new question about this. (But most likely it will be marked as a duplicated.) If you really just want to tap out on this and move on, you could use a `const_cast` to just get the consts right. That will look pretty ugly to C++ programmers though. – Chris Beck Aug 26 '15 at 15:35
  • @Beck I've been struggling with this for two days. At this point I could care less if it's ugly or not, I just want to get beyond this hurtle. I looked into both links and I'm still in the same position. I will tap out on this and just ask a different question. Thanks for your help though! – user1646428 Aug 26 '15 at 15:42
0

You should be using execv. When you convert to execv, for some reason execv expects a array of non-const pointers instead of const pointers, so you either have to just cast the array to (char**) or copy the strings into (char*) pointers.

  • Thanks for the help pinkhorror! I thought I was copying the strings into (char*) pointers in the second example listed above using the 'Value' variable... apparently not... Any thoughts? – user1646428 Aug 26 '15 at 16:10
  • Your child_argv is an array of `const char*`. `execv` has an array of (char*) as its expected argument (I don't know why, but it does.) With C types, I'm probably simplifying a bit, but you read right to left. So, `const char* child_argv[10]` is a 10-element array of pointers to chars that are const. execv has this as it's second argument: `char *const argv[]` So, that's an array of const pointers to chars. It promises not to modify the pointers themselves, but the chars they point to are fair game. – pinkhorror Aug 26 '15 at 16:24
  • thanks for the help! So are you saying I need to change "const char* child_argv[10]" to "char *const argv[]"? Sorry about this... As stated I've worked on this for two days, I'm tired, I'm frustrated, and this problem is holding up development on several fronts. – user1646428 Aug 26 '15 at 18:29
  • Thanks again for your help, I ended up going at this from a different direction and have updated the post to reflect that. – user1646428 Aug 26 '15 at 20:14