/* 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;
}