1

I am writing a simple command line interpreter. My code reads a string using scanf and parses it using the function getArgs() shown below, and then uses that array as an argument to execvp to perform a command such as ls. It works if I call only 'ls' but when I call 'ls -la', it gives the same result as 'ls'.

void getArgs(char* command, char* args[]){

    int i = 0;
    char* p = strtok(command, " "); 
    args[i] = p;

    while(p != NULL){
        i++; 
        p = strtok(NULL, " ");
        args[i] = p;
}
}

Here is my main function which includes the initialization of the arguments given:

int main(){
char *args[1024];
char example[30]; 
char exit[5] = {'q', 'u', 'i', 't', '\0'};
int f1; 
int status;
size_t n = sizeof(args)/sizeof(args[0]);

while(strncmp(example, exit, 30) !=0){

    printf(">>>");
    scanf("%s", example);
    getArgs(example, args);
    int x = strncmp(args[0], exit, 30);

    if (x != 0){
        f1 = fork(); 
        if (f1 != 0){
            /* wait  for child process to terminate */
            waitpid(f1, &status, 0);
        }
        else{myExec(args);}}         
    else{
        return 0;}}
    return 0; 
}

My guess as to the problem is that my argument array, args, is not null terminated and so when I attempt to use it in myExec():

void myExec(char* args[]){
    execvp(args[0], args);
}

this does not work. So my question is, can I set the item after the last non-empty part of my array to null to try to get this to work? If so, how can I do that? Is there a better way to solve this?

2
  • I added the rest of the code, also args[i] = strdup(p); gives 'Segmentation error: 11'. Commented Mar 29, 2019 at 19:46
  • char exit[] = "quit"; Commented Mar 29, 2019 at 19:49

2 Answers 2

1

The -la is being ignored because scanf("%s", example); will stop at the first space. I suggest

scanf(" %29[^\n]", example);

Which will

  • Ignore whitespace left in the buffer from the previous command.
  • Restrict the string input from overflowing.
  • Allow space seperators in the command.

Note too that in the first execution of while(strncmp(example, exit, 30) !=0) the example is an uninitialised variable, so that needs to be

char example[30] = "";
Sign up to request clarification or add additional context in comments.

Comments

1

The %s directive stops scanning at the first whitespace character, so it won't properly capture any commands with spaces (such as ls -la). You should use fgets to get user input if you want to preserve any whitespace:

if ( fgets( example, sizeof example, stdin ) )
{
  getArgs( example, args);
  ...
}

fgets will read up to sizeof example - 1 characters into example (including the newline!) and 0-terminate the string. You may want to take that newline into account with your strtok call.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.