Minishell InKwan Yu
Topics Unix System calls waitpid() pipe() dup2() C function calls strtok() strcmp() Minishell Software Enginnering tip Evolutionary & Iterative
Unix System calls waitpid() For out purpose: waitpid(pid, 0, 0); Blocking wait for a child until it terminates For Project 1, every child is waited until they all terminate
Unix System calls Ex #include main() { int pid; if ((pid = fork()) ==0) { print("This is the child\n"); // execvp() can be here. } else { waitpid(pid, 0, 0); // wait until the child terminates printf("This is the parent\n"); }
Unix System calls pipe() Creates pipes dup2() Duplicates an open file descriptor Next slides will show how they work pipe() and dup2() should be used to implement ‘|’ operator in the shell
File Descriptor/Table/i-node fd 0 fd 1 fd 2 fd 3 fd 4 Descriptor table [one table per process] Open file table [shared by all processes] i-node table [shared by all processes] File pos refcnt==1... File pos Refcnt==1... stderr stdout stdin File access... File size File type File access... File size File type File A (terminal) File B (disk)
pipe() Call int pfd[2]; pipe(pfd); fd 0 fd 1 fd 2 fd 3 fd 4 Descriptor table (one table per process) Open file table (shared by all processes) i-node table (shared by all processes) File pos Refcnt==1... File pos Refcnt==1... File access... File size File type Pipe 0 Pipe 1 pfd[1] pfd[0]
After the First fork() fd 0 fd 1 fd 2 fd 3 fd 4 Descriptor tables Open file tablei-node table File pos refcnt==2... File pos refcnt==2... Parent's table fd 0 fd 1 fd 2 fd 3 fd 4 Child's table File access... File size File type Pipe 0 Pipe1 fork(); pfd[1] pfd[0] pfd[1] pfd[0] File access... File size File type
Child dup2() fd 0 fd 1 fd 2 fd 3 fd 4 Descriptor tables Open file tablei-node table File pos refcnt=2... File pos refcnt=2... Parent's table fd 0 fd 1 fd 2 fd 3 fd 4 Child 1's table File access... File size File type File access... File size File type Pipe 0 Pipe1 dup2(pdf[1], STDOUT_FILENO); // in forked child // STDOUT_FILENO == 1 close(pdf[1]);
Finally after Two fork()s, dup2()s, and close()s fd 0 fd 1 fd 2 fd 3 fd 4 File pos refcnt==1... File pos refcnt==1... Child 1's table fd 0 fd 1 fd 2 fd 3 fd 4 Child 2's table File access... File size File type pipe 0 pipe 1 fd 0 fd 1 fd 2 fd 3 fd 4 Parent's table stdout stdin stdout stdin
C Function Calls strtok() Stg type variables are strings terminating with zero (0) typedef of Stg in arabildr.h and stgbildr.h should be factored out into main.h strtok() can be used to generate a parsed argument to execvp() Takes two arguments The first argument is a string to be parsed The second argument is a string of delimiters
C Function Calls strtok() The string in the first argument is altered after strtok() call The first argument should be in write-able memory For exmaple, Stg cmd = “Hello, World”; may not work Initialized strings can be placed in BSS region (read- only)
C Function Calls strtok() // Stg cmd has “Hello,I am here” Arabildr ar_bildr = arabildr_init(); Stg tok = strtok(cmd, ","); // tok has “Hello” arabildr_append(arr_bildr, tok); tok = Stg strtok(NULL, ","); // tok has “I” arabildr_append(arr_bildr, tok); tok = Stg strtok(NULL, ","); // tok has “am” arabildr_append(arr_bildr, tok); tok = Stg strtok(NULL, ","); // tok has “here” arabildr_append(arr_bildr, tok); tok = Stg strtok(NULL, ","); // tok == NULL; The end AraOfStgs cmd_array = arabildr_array(arr_bildr); “Hello” “I” “am” “Here” 0 cmd_array[0] cmd_array[4]
C Function Calls strcmp() Compares two zero terminated strings If they are exact match, returns 0 Else returns nonzero
C Function Calls strcmp() Arabildr ar_bildr = arabildr_init(); arabildr_append(arr_bildr, “exit”); AraOfStgs cmd_array = arabildr_array(arr_bildr); ; // cmd_array[0] is assigned to “exit” int match = strcmp(cmd_array[0], “exit”); printf(“match %d\n”, match);
Minishell SE tip 1 st step Read user input & display : getchar() 2 nd step Parse the input : strtok() 3 rd step Run the program : fork(), exec(), waitpid(), strcmp() 4 th step Run the piped programs : pipe(), dup2()
Minishell SE tip 1 st step While(1) { Read a user key stoke using getchar() Use Stgbildr APIs to accumulate the user input Display the input when ‘\n’ is encountered Destroy the Stgbildr object }
Minishell SE tip 2 nd step While(1) { Get the user input Parse the input using strtok() Use Arabildr APIs Display Arabildr objects AraOfStgs type variable is useful in displaying }
Minishell SE tip 3 rd step While(1) { Get the user input Parse the input Use strcmp() to “exit”, “logout” or “quit” ; if yes then exit(); Run the non-piped program fork() Parent: waitpid() for the child Child: execvp() using AraOfStgs type argument Destroy objects }
Minishell SE tip 4 th step While(1) { Get the user input Parse the input strcmp() to “exit” Check if ‘|’ exist in the input If yes run the piped programs Two children are created; pipe() and dup2() are helpful for ‘|’ strtok(), pipe(), dup2(), 2*fork(), 2*execvp(), 2*waitpid() Else run the non-piped program strtok(), fork(), execvp(), waitpid() Destroy objects }
Further Information Advanced Programming in the UNIX Environment, Addison-Wesley, 1992, ISBN: Design of the UNIX Operating System, Prentice Hall, 1986, ISBN: