2

I have a vector named tokens that holds the command in tokens[0] and args as the rest of the vector. I am trying to convert the vector so I can make the call to execvp(args[0], args); Currently args[0] and args just print as memory addresses.

  char **args = (char**)malloc(tokens.size() * sizeof(string));
  char *arg;

  int i;
  for(i = 0; i < tokens.size(); i++)
  {
    arg = &tokens[i][0];
    args[i] = arg;
  }
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Alejandro
  • 73
  • 7

2 Answers2

4

You don't have to resort to malloc to perform this since you are already using vectors of strings.

You could just create a std::vector<char*> before calling execvp:

std::vector<char*> pvec(tokens.size());
std::transform(tokens.begin(), tokens.end(), pvec.begin(), [](auto& str) {
  return &str[0];
});
pvec.data(); // This is a char**, pass it to `execvp`
Fatih BAKIR
  • 4,569
  • 1
  • 21
  • 27
  • @Alejandro, awesome! You can also mark it as so by clicking the little tick below the up/down arrows :) – Fatih BAKIR Mar 01 '22 at 00:13
  • Actually this only works when execvp is only given the first parameter pvec.data()[0]. When I make this call execvp(pvec.data()[0], pvec.data()), programs with arguments do not work. In my case I am running /usr/bin/xterm -bg green. *note - I don't have enough reputation to upvote your post unfortunately. – Alejandro Mar 01 '22 at 00:16
  • That might have something to do with how you construct `tokens`. This just converts that vector to a vector of `char*`s. What do you have in `tokens` for `/usr/bin/xterm -bg green`? – Fatih BAKIR Mar 01 '22 at 00:22
2

I found that the answer lies with adding the NULL terminator to the end of the vector so that execvp knows where to end pvec.data(); This is thanks to Fatih above.

  std::vector<char*> pvec(tokens.size());
  std::transform(tokens.begin(), tokens.end(), pvec.begin(), [](auto& str) {
    return &str[0];
  });
  pvec.push_back(NULL);
  pvec.data();

  pid = fork();
  // if we enter child process
  if (pid == 0)
  {
    if (execvp(pvec.data()[0], pvec.data()) == -1)
    {
      printf("right here officer\n");
    }
    exit(EXIT_FAILURE);
  }```
Alejandro
  • 73
  • 7