aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--sh/parser.c33
-rw-r--r--sh/sh.c26
3 files changed, 38 insertions, 22 deletions
diff --git a/.gitignore b/.gitignore
index f77c74f..009c415 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
./box
*/bin/*
box_tmp/*
+./sh/sh
diff --git a/sh/parser.c b/sh/parser.c
index fa91a3f..17e7a58 100644
--- a/sh/parser.c
+++ b/sh/parser.c
@@ -15,11 +15,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#define _POSIX_C_SOURCE 200809L
+
/* POSIX Header Files */
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
/* sh Header Files */
#include "parser.h"
@@ -35,13 +39,36 @@ int splitCommand(char [4096], char *[4096]);
* DESCRIPTION
* -----------
* Parse a shell command and determine if the command to run is built-in or
- * external. It then runs the command if it's built-in, or returns 127 if the
- * command isn't built-in. <It also could in the future handle tokens.>
+ * external. It then runs the command accordinately.
+ * <It also could in the future handle tokens.>
*/
int parseCommand(int argc, char *argv[]) {
+ struct sigaction signal_action;
+ int status_code = 0;
+ pid_t isparent;
if (!strcmp(argv[0], "cd")) return builtin_cd(argc, argv);
- else return 127; /* The command isn't built-in, exit! */
+ /* The command isn't built-in. */
+ isparent = fork();
+ wait(&status_code);
+ if (!isparent) {
+ /* Do not ignore SIGINT when in a child process. */
+ signal_action.sa_handler = SIG_DFL;
+ sigemptyset(&signal_action.sa_mask);
+ sigaction(SIGINT, &signal_action, NULL);
+ /* Some sh implementations manually search for the command in PATH.
+ * This is not needed here because execvp is going to search for
+ * that command in PATH anyway.
+ */
+ status_code = execvp(argv[0], argv);
+ /* If the child process is still alive, we know execvp(3) failed. */
+ exit(127);
+ }
+ /* This code may be used to store the exit value in $?. */
+ //if (errno != EINTR && WEXITSTATUS(status_code) !=) return WEXITSTATUS(status_code);
+ //else return 0;
+ if (WEXITSTATUS(status_code) == 127) return 127;
+ return 0;
}
/* USAGE
diff --git a/sh/sh.c b/sh/sh.c
index f3b5d88..3bd0843 100644
--- a/sh/sh.c
+++ b/sh/sh.c
@@ -18,7 +18,7 @@
/* Define feature test macro. It doesn't compile with gcc without that for
* some reason.
*/
-#define _POSIX_C_SOURCE 1
+#define _POSIX_C_SOURCE 200809L
/* POSIX Header files */
#include <stdio.h>
@@ -99,28 +99,16 @@ void commandLoop(int isinteractive) {
setvbuf(stdout, NULL, _IONBF, 0);
if (isinteractive) { printf(prompt); }
read(STDIN_FILENO, name, 4096);
- if (!strcmp(name, "\n")) {
+ if (!strcmp(name, "\n"))
continue;
+ else if (*name == 0 || *name == EOF) {
+ putchar('\n');
+ break;
}
name[strlen(name) - 1] = 0;
command_argc = splitCommand(name, command); /* See parser.c */
- if (parseCommand(command_argc, command) == 127 /* See parser.c */ ) {
- isparent = fork();
- wait(NULL);
- if (!isparent) {
- /* Do not ignore SIGINT when in a child process. */
- signal_action.sa_handler = SIG_DFL;
- sigemptyset(&signal_action.sa_mask);
- sigaction(SIGINT, &signal_action, NULL);
- /* Some sh implementations manually search for the command in PATH.
- * This is not needed here because execvp is going to search for
- * that command in PATH anyway.
- */
- return_code = execvp(command[0], command);
- /* If the child process is still alive, we know execvp(3) failed. */
- printf("sh: %s: %s\n", command[0], strerror(errno));
- exit(0);
- }
+ if ((errno = parseCommand(command_argc, command)) != 0 /* See parser.c */ ) {
+ printf("sh: %s: %s\n", command[0], strerror(errno));
}
}
}