Shell is an important tool in Unix/Linux to parse user input commands. Next we will implement a simple shell program to practiceFork/exec/Wait/exitBy the way, we recommend a book titled understanding Unix/Linux programming-A Guide to theory and practice, which is well written and suitable for beginners in Unix/Linux programming.
The main program of our shell is as follows:
1 int main(void) 2 { 3 char *cmdline; 4 char *prompt; 5 char **arglist; 6 int result; 7 8 prompt = PROMPT; 9 signal(SIGINT, SIG_IGN);10 signal(SIGQUIT,SIG_IGN);11 12 while ((cmdline = next_cmd(prompt, stdin)) != NULL) {13 if ((arglist = split_line(cmdline)) != NULL) {14 result = execute(arglist);15 freelist(arglist);16 }17 free(cmdline);18 }19 20 return 0;21 }
Where,Next_cmd ()The main function of a function is to read the next command from the input stream, and return null when the file Terminator is reached. The code for this function is as follows:
1 char *next_cmd(char *prompt, FILE *file) 2 { 3 char *cmdline; 4 int length = 0; 5 int c; 6 int location = 0; 7 8 printf("%s", prompt); 9 10 while ((c = getc(file)) != ‘\n‘) {11 if (location + 1 >= length) {12 cmdline = (char *)malloc(BUFSIZ);13 length = BUFSIZ;14 } 15 else if (location >= BUFSIZ) {16 cmdline = realloc(cmdline, length + BUFSIZ);17 length += BUFSIZ;18 }19 cmdline[location++] = c;20 }21 cmdline[location] = ‘\0‘;22 23 return cmdline;24 }
Split_line ()The main function of the function is to split the input string into a string array, which ends with null. The code for this function is as follows:
1 char **split_line(char *cmd) 2 { 3 char **arglist; 4 int row = 0; 5 int len = 0; 6 char *cp = cmd; 7 char *start = cmd; 8 arglist = malloc(BUFSIZ); 9 10 while (*cp != ‘\0‘) {11 while (*cp != ‘ ‘ && *cp != ‘\t‘) {12 ++cp;13 ++len;14 }15 arglist[row] = malloc(len + 1);16 strncpy(arglist[row], start, len);17 ++row;18 len = 0;19 while (*cp == ‘ ‘ || *cp == ‘\t‘) {20 ++cp;21 }22 start = cp;23 }24 arglist[row] = NULL;25 26 return arglist;27 }
Execute ()The main function of a function is to use fork, execvp, and wait functions to run a command and return the end state of the command. The code for this function is as follows:
1 int execute(char **argv) 2 { 3 pid_t pid; 4 int child_info = -1; 5 6 if ((pid = fork()) == -1) { 7 perror("fork error"); 8 } 9 10 if (pid == 0) {11 signal(SIGINT, SIG_DFL);12 signal(SIGQUIT, SIG_DFL);13 execvp(argv[0], argv);14 perror("exec error");15 exit(1);16 }else {17 if (wait(&child_info) == -1) {18 perror("wait error");19 }20 }21 22 return child_info;23 }
Freelist ()The function is to release the space of the string array allocated above. The code for this function is as follows:
1 void freelist(char **list) 2 { 3 char **cp = list; 4 while (*cp) { 5 free(*cp); 6 ++cp; 7 } 8 9 free(list);10 }
Due to the limited personal level, you are welcome to discuss, Do not spray, thank you !!
Simple shell implementation