/* shell.c * A very simple shell. * * Les Harris 9/30/07, SOS */#include <stdlib.h>#include <stdio.h>#include <sys/wait.h>#include <sys/types.h>#include <unistd.h>#include <string.h>#include <errno.h>#define DEBUG#ifndef TRUE #define TRUE 1#endif#define BUFFER_SIZE 2048#define PARAM_BUFFER_SIZE 512#define MAX_PARAMETERS 256void type_prompt(void);void read_command(char *command, char *argv[]);void clear_data(char *command, char *argv[]);void init_params(char *argv[]);int main(int argc, char *argv[]) { char command[BUFFER_SIZE]; char *parameters[MAX_PARAMETERS]; int status; /* Null out the parameter array so I know whats in it */ init_params(parameters); while(TRUE) { type_prompt(); clear_data(command, parameters); read_command(command, parameters); if(fork() != 0) waitpid(-1, &status, 0); else { errno = 0; execv(command, parameters);#ifdef DEBUG printf("errno: %d\n", errno);#endif /* The following should be made far more user friendly */ if(errno != 0) fprintf(stderr, "There was an error: Error %d\n", errno); } } clear_data(command, parameters); return 0;}/** * type_prompt * Prints the prompt for the user. */void type_prompt(void) { printf("$ ");}/** * read_command * Reads a line of input into the passed command string and * string array. * * @param command a pointer to a char array * @param argv a pointer to a string array */void read_command(char *command, char *argv[]) { char line[BUFFER_SIZE]; char *chunk; fgets(line, BUFFER_SIZE, stdin); /* This trims off the trailing newline so * it doesn't get passed to the command as an * argument */ int j; for(j = 0; j < strlen(line); j++) if(line[j] == '\n') line[j] = '\0'; /* Begins the tokenization process, delimating on space * and copys the first word into the command argument */ chunk = strtok(line, " "); strncpy(command, chunk, BUFFER_SIZE);#ifdef DEBUG printf("\nCommand:\n\t%s\nParams:\n", command);#endif /* POSIX standard states the name of the program will * be passed to it as its first argument so we do it * manually here. */ argv[0] = malloc(sizeof(char) * PARAM_BUFFER_SIZE); strncpy(argv[0], command, PARAM_BUFFER_SIZE);#ifdef DEBUG printf("\t%s\n", argv[0]);#endif /* i is 1 because argv[0] contains the name of the program */ int i = 1; while(chunk != NULL && i < MAX_PARAMETERS) { chunk = strtok(NULL, " "); if(chunk == NULL) { argv[i] = NULL;#ifdef DEBUG printf("\t<NULL>\n");#endif } else { argv[i] = malloc(sizeof(char) * PARAM_BUFFER_SIZE); strncpy(argv[i], chunk, PARAM_BUFFER_SIZE);#ifdef DEBUG printf("\t%s\n", argv[i]);#endif } i++; }}/** * clear_data * Clears the command string and parameter array. * * @param command the command string * @param argv the parameter string array */void clear_data(char *command, char *argv[]) { int i; /* Null out our buffers and free malloced * memory if needed. */ for(i = 0; i < BUFFER_SIZE; i++) command[i] = '\0'; for(i = 0; i < MAX_PARAMETERS; i++) { if(argv[i] != NULL) free(argv[i]); argv[i] = NULL; }}/** * init_params * Nulls out the parameter array */void init_params(char *argv[]) { int i; /* Set the array null to put it into a known state */ for(i = 0; i < MAX_PARAMETERS; i++) argv[i] = NULL;}