diff options
Diffstat (limited to '')
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | sh/parser.c | 33 | ||||
-rw-r--r-- | sh/sh.c | 26 |
3 files changed, 38 insertions, 22 deletions
@@ -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 @@ -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)); } } } |