aboutsummaryrefslogtreecommitdiff
path: root/lab5_shelllab/helper-routines.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lab5_shelllab/helper-routines.cc')
-rw-r--r--lab5_shelllab/helper-routines.cc131
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;
+}