-2
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_LINE 1024

void run_shell(char * cmd){
        char * str = cmd;
        int size = strlen(str);
        char blank[] = " ";

        char * token = strtok(str, blank);

        char * argv[3];
        int i = 0;
        while(token != NULL){
                argv[i] = token;
                i++;
                token = strtok(NULL, blank);
        }

        argv[i] = NULL;

        pid_t pid;

        if((pid = fork()) == 0){
                if(execvp(argv[0], argv) < 0){
                        perror("Invalid Command!\n");
                        exit(0);
                }
        }
        else{
                if(waitpid(pid, NULL, 0) < 0){
                        perror("Some Problem Program!\n");
                        exit(0);
                }
        }
        printf("\n");
}

int main(){
        char comand[MAX_LINE];
        char * username;

        printf("Eter your name : ");
        scanf("%s", username);

        while(1){
                char cwd[MAX_LINE];
                getcwd(cwd, sizeof(cwd));

                printf("%s %s$ > ", username, cwd);

                fgets(comand, MAX_LINE, stdin);

                printf("\n");
                run_shell(comand);
        }
}

I'm making a small shell. But when I enter a command, the execvp function causes an error. When I print out argv[], I can see that it has been tokenized without any problems. It's hard to guess the my code internal movement because I don't know much about the standard input/output. What's the problem? What should I fix?

김정훈
  • 1
  • 1

1 Answers1

2

Your program has at least three problems:

  • char * username; does not initialize username to point to anything, so it is uninitialized when scanf("%s", username); executes. For a beginner-level program, you can define username as char username[1024];.
  • In scanf("%s", username);, the user types some characters and then presses enter/return, which puts a new-line character into the stream. scanf reads the non-white-space characters and leaves the new-line character in the stream. Then the later fgets reads that new-line character, resulting in a line that is empty except for that character.
  • In fgets(comand, MAX_LINE, stdin);, fgets reads until it finds a new-line character (or the buffer is full). It leaves that new-line character in the buffer, at the end. You should remove it.

Note that none of these is a problem with execvp, which shows that the title “The execvp function does not work exactly” is false. When debugging programs, analyze the parts carefully. Do not assume the step where the failure appears is the step that caused the failure. Examine the values of objects (variables) at various points in the program to ensure the steps from beginning to end are proceeding as desired. When examining strings, pay attention to “invisible” characters.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312