/* File: ~liux/public_html/courses/cop4610/examples/simple-shell.cc Purpose: Demonstrate how to use fork and exec system calls to develop a simple shell Author: Xiuwen Liu, On the web: http://www.cs.fsu.edu/~liux/courses/cop4610/examples/simple-shell.cc Compile: g++ -o simple-shell simple-shell.cc */ #include #include #include #include #include #include #include #include #define MAX_LINE 512 #define MAX_ARG 50 extern char **environ; int Parse_Command(char *buf, char *argv_list[]); int main(void) { char buf[MAX_LINE]; int status; char *my_argv[MAX_ARG]; int my_argc; int i; int pid; do { printf("Next command -> "); /* Display prompt */ buf[0]='\0'; cin.getline(buf,MAX_LINE); if (buf[0] == '\0') continue; if (buf[strlen(buf)-1]=='\n') { buf[strlen(buf)-1]=0; } my_argc = Parse_Command(buf, my_argv); cout << "There are " << my_argc << " input arguments." << endl; for (i=0; i < my_argc; i++) { cout << "\t" << i+1 << "th = " << my_argv[i] << endl; } if (my_argc == 0) continue; if (strcmp(my_argv[0],"myexit") ==0) break; if (strcmp(my_argv[0],"myenv")==0) { while(environ[i] != NULL) { cout << environ[i] << endl; i++; } } else { if ( (pid = fork()) < 0) { cerr << "Counld not create new process." << endl; } else { if (pid ==0) { /* Child */ cout << endl << "Child " << getpid() << " started\n"; if (execvp(my_argv[0],my_argv)<0) { cerr << "Could not execute \"" << my_argv[0] << "\".\n"; perror("execvp"); exit(-1); } } /* Parent */ if((pid = waitpid(pid, &status, 0)) < 0) { cout << "System call \"waitpid\" error.\n"; } cout << "\nChild " << pid << " exited with status = " << status << ".\n"; } } } while(1); return 0; } int Parse_Command(char *buf, char *argv_list[]) { int now_argc = 0; char *bufp; bufp = strtok(buf, " \t"); argv_list[now_argc] = bufp; if (bufp == NULL) return now_argc; now_argc++; while (bufp != NULL && now_argc < MAX_ARG) { bufp = strtok(NULL," \t"); argv_list[now_argc++] = bufp; } now_argc --; /* Because the last one is an empty string */ if (bufp != NULL) { cerr << "Argument list too long.\n"; } return now_argc; }