2
fgets(command, BUFFSIZE, stdin);
command[strlen(command)-1] = '\0';

char *p = strtok(command, " ");
char *command_tok[BUFFSIZE];
int i = 0;
while (p) {
    command_tok[i++] = p;
    p = strtok(NULL, " ");
}


char *commands[] = {*command_tok, NULL};
execvp(command_tok[0], commands);

I try to get user's input, tokenize it and store command and arguments in an array to pass it to execvp(). However, the arguments are never read. If the input is "ls -l", it is always executed as "ls".

3 Answers3

4

This line:

// makes a two element array
char *commands[] = {*command_tok, NULL};

is wrong.

It's creating a new array consisting of just two elements, the first of which is command_tok[0]. Instead what you want is

   command_tok[i] = NULL
   execvp(command_tok[0], command_tok);

Also

command[strlen(command)-1] = '\0'

is nonsensical: strlen finds the length by searching for the null byte, which you then set to null again.

Here's my version:

#include <string.h>
#include <unistd.h>

#include <cstdio>
static const int BUFFSIZE=200;

int main(int argc, char* argv[]) {
  char command[BUFFSIZE] = { 0 };
  fgets(command, BUFFSIZE, stdin);
  // remove trailing new line if present
  commmand[strcspn(command, "\n")] = 0;

  char *p = strtok(command, " ");
  char *command_tok[BUFFSIZE];
  int i = 0;
  while (p) {
    command_tok[i++] = p;
    p = strtok(NULL, " ");
  }

  command_tok[i] = NULL;
  execvp(command_tok[0], command_tok);
}

The one-liner for removing trailing new line came from Removing trailing newline character from fgets() input

Community
  • 1
  • 1
eyeApps LLC
  • 643
  • 4
  • 10
1

After the -l you don't have the space, so, your option takes the '-l\n' as the argument. So you have to use the '\n' is also in the separator in the strtok function.

The below code will work as you expected.

fgets(command, BUFFSIZE, stdin);
command[strlen(command)-1] = '\0';

char *p = strtok(command, " \n");
char *command_tok[BUFFSIZE];
int i = 0;
while (p) {
    command_tok[i++] = p;
    p = strtok(NULL, " \n");
}
command_tok[i] = NULL;

execvp(command_tok[0], command_tok);

When you use fgets to read the input, If it is not an EOF, you have \n at last. So, using this you can choose the argument.

0

You provide to commands an array that consists exactly of two elements: the (first) element command_tok points to, and NULL. How should the compiler know that you mean all elements of an array command_tok, and how should it determine its size?

Matthias
  • 8,018
  • 2
  • 27
  • 53