Skip to content
Advertisement

writing a shell in C my program is not able to exit()

I am writing a program to implement a simple shell in C but when I execute the program at the end when I type exit it does not exit.

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#define BUFFER_LEN 1024

int main()
{
        char line[BUFFER_LEN];  //get command line
        char *argv[100];        //user command
        char *path = "/bin/";   //set path at bin
        char progpath[20];      //full file path
        int argc;               //arg count

        while (1) {

                printf("My shell>> ");  //print shell prompt

                if (!fgets(line, BUFFER_LEN, stdin)) {  //get command and put it in line
                        size_t length = strlen(line);
                        if (line[length - 1] == 'n')
                        line[length - 1] = '';
                        break;  //if user hits CTRL+D break
                }
                if (strcmp(line, "exit") == 0) {        //check if command is exit
                        exit(0);
                        break;
                }

                char *token;    //split command into separate strings
                token = strtok(line, " ");
                int i = 0;
                while (token != NULL) {
                        argv[i] = token;
                        token = strtok(NULL, " ");
                        i++;
                }
                argv[i] = NULL; //set last value to NULL for execvp

                argc = i;       //get arg count
                for (i = 0; i < argc; i++) {
                        printf("%sn", argv[i]);        //print command/args
                }
                strcpy(progpath, path); //copy /bin/ to file path
                strcat(progpath, argv[0]);      //add program to path

                for (i = 0; i < strlen(progpath); i++) {        //delete newline
 if (progpath[i] == 'n') {
                                progpath[i] = '';
                        }
                }
                int pid = fork();       //fork child

                if (pid == 0) { //Child
                        execvp(progpath, argv);
                        fprintf(stderr, "Child process could not do execvpn");

                } else {        //Parent
                        wait(NULL);
                        printf("Child exitedn");
                }

        }
}

I am executing in on cygwin hence a.exe is generated.

execution of program

$ ./a.exe
My shell>> ls
ls

a.exe  p3.4.cpp  p3.6.cpp  p3.6.cpp~  p3.7.cpp  p3.7.cpp~  p3.cpp  shell.c  shell.c~  test.txt
Child exited
My shell>> cat test.txt
cat.txt

Child process could not do execvp
My shell>> exit
exit

Child process could not do execvp
My shell>> exit()
exit()

Child process could not do execvp
My shell>> exit
exit

Child process could not do execvp
My shell>> exit
exit

Here you can see in the above output the program is not able to exit when I am typing an exit on the command prompt. What is the mistake I am doing in above program?

Advertisement

Answer

You probably mixed removing the new line with the handling of CTRL-D. Your code

if (!fgets(line, BUFFER_LEN, stdin)) {  //get command and put it in line
                    size_t length = strlen(line);
                    if (line[length - 1] == 'n')
                    line[length - 1] = '';
                    break;  //if user hits CTRL+D break
}

removed the new line only if fgets fails, e.g. end of file has been reached. Also, line[length-1] will yield undefined behaviour if length==0.

I’d replace the logic:

if (!fgets(line, BUFFER_LEN, stdin)) {  //get command and put it in line
   break;  //if user hits CTRL+D break
} else {
   line[strcspn(line, "n")] = '';
}
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement