Can anyone please look at this code for a simple shell in C
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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
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;
}
Solution
I am not 100% sure about the solution but you may give try to this one. In place of void in int main function arguments you can use command line arguments to take multiple commands from the user i.e., you can have the following line of code in order to receive multiple command line arguments.
Do tell me if this works. Hope it helps.


