diff options
Diffstat (limited to 'lab5_shelllab/helper-routines.cc')
-rw-r--r-- | lab5_shelllab/helper-routines.cc | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lab5_shelllab/helper-routines.cc b/lab5_shelllab/helper-routines.cc new file mode 100644 index 0000000..0af221d --- /dev/null +++ b/lab5_shelllab/helper-routines.cc @@ -0,0 +1,131 @@ +#include "helper-routines.h" +#include "globals.h" +#include <stdio.h> +#include <strings.h> +#include <memory.h> // strcpy and memcpy +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> + +/*********************** + * Other helper routines + ***********************/ + +/* + * usage - print a help message + */ +void usage(void) +{ + printf("Usage: shell [-hvp]\n"); + printf(" -h print this message\n"); + printf(" -v print additional diagnostic information\n"); + printf(" -p do not emit a command prompt\n"); + exit(1); +} + +/* + * unix_error - unix-style error routine + */ +void unix_error(const char *msg) +{ + fprintf(stdout, "%s: %s\n", msg, strerror(errno)); + exit(1); +} + +/* + * app_error - application-style error routine + */ +void app_error(const char *msg) +{ + fprintf(stdout, "%s\n", msg); + exit(1); +} + +/* + * Signal - wrapper for the sigaction function + */ +handler_t *Signal(int signum, handler_t *handler) +{ + struct sigaction action, old_action; + + action.sa_handler = handler; + sigemptyset(&action.sa_mask); /* block sigs of type being handled */ + action.sa_flags = SA_RESTART; /* restart syscalls if possible */ + + if (sigaction(signum, &action, &old_action) < 0) + unix_error("Signal error"); + return (old_action.sa_handler); +} + +/* + * sigquit_handler - The driver program can gracefully terminate the + * child shell by sending it a SIGQUIT signal. + */ +void sigquit_handler(int sig) +{ + printf("Terminating after receipt of SIGQUIT signal\n"); + exit(1); +} + +/* + * parseline - Parse the command line and build the argv array. + * + * Characters enclosed in single quotes are treated as a single + * argument. Return true if the user has requested a BG job, false if + * the user has requested a FG job. + */ +int parseline(const char *cmdline, char **argv) +{ + static char array[MAXLINE]; /* holds local copy of command line */ + char *buf = array; /* ptr that traverses command line */ + char *delim; /* points to first space delimiter */ + int argc; /* number of args */ + int bg; /* background job? */ + + strncpy(buf, cmdline, MAXLINE); + buf[strlen(buf) - 1] = ' '; /* replace trailing '\n' with space */ + while (*buf && (*buf == ' ')) /* ignore leading spaces */ + buf++; + + /* Build the argv list */ + argc = 0; + if (*buf == '\'') + { + buf++; + delim = strchr(buf, '\''); + } + else + { + delim = strchr(buf, ' '); + } + + while (delim) + { + argv[argc++] = buf; + *delim = '\0'; + buf = delim + 1; + while (*buf && (*buf == ' ')) /* ignore spaces */ + buf++; + + if (*buf == '\'') + { + buf++; + delim = strchr(buf, '\''); + } + else + { + delim = strchr(buf, ' '); + } + } + argv[argc] = NULL; + + if (argc == 0) /* ignore blank line */ + return 1; + + /* should the job run in the background? */ + if ((bg = (*argv[argc - 1] == '&')) != 0) + { + argv[--argc] = NULL; + } + return bg; +} |