Question: Can anyone please look at this code for a simple shell in C and determine how to accept multiple commands at the prompt when separated
Can anyone please look at this code for a simple shell in C and determine how to accept multiple commands at the prompt when separated by a ";"? The following code works with one command (for example, when "ls" is entered at the prompt) but fails when the command entered is something like "ls ; grep foo".
/* ----------------------------------------------------------------- */
/* PROGRAM shell.c */
/* This program reads in an input line, parses the input line */
/* into tokens, and use execvp() to execute the command. */
/* ----------------------------------------------------------------- */
#include
#include
#include
#include
#include
#include
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
/* ----------------------------------------------------------------- */
/* FUNCTION parse: */
/* This function takes an input line and parse it into tokens. */
/* It first replaces all white spaces with zeros until it hits a */
/* non-white space character which indicates the beginning of an */
/* argument. It saves the address to argv[], and then skips all */
/* non-white spaces which constitute the argument. */
/* ----------------------------------------------------------------- */
void parse(char *line, char **argv)
{
static char* delimiter = " ; \t";
//static char* delimiter = " \t";
char *token = strtok(line, delimiter);
while (token != NULL) {
*argv++ = token;
token = strtok(NULL, delimiter);
}
*argv = (char *)'\0'; /* mark the end of argument list */
}
/* ----------------------------------------------------------------- */
/* FUNCTION execute: */
/* This function receives a command line argument list with the */
/* first one being a file name followed by its arguments. Then, */
/* this function forks a child process to execute the command using */
/* system call execvp(). */
/* ----------------------------------------------------------------- */
void execute(char **argv)
{
pid_t pid;
int status;
if ((pid = fork()) < 0) { /* fork a child process */
printf("*** ERROR: forking child process failed ");
exit(1);
}
else if (pid == 0) { /* for the child process: */
if (execvp(*argv, argv) < 0) { /* execute the command */
printf("*** ERROR: exec failed ");
exit(1);
}
}
else { /* for the parent: */
while (wait(&status) != pid) /* wait for completion */
;
}
}
/* ----------------------------------------------------------------- */
/* The main program starts here */
/* ----------------------------------------------------------------- */
int main(void)
{
char line[1024]; /* the input line */
char *argv[64]; /* the command line argument */
char *c = NULL;
printf("Shell -> "); /* display a prompt */
while (fgets(line, sizeof(line), stdin)) {
/* repeat until EOF .... */
parse(line, argv); /* parse the line */
if (strcmp(argv[0], "exit") == 0) /* is it an "exit"? */
exit(0); /* exit if it is */
execute(argv); /* otherwise, execute the command */
printf("Shell -> "); /* display a prompt */
}
return 0;
}
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
