From bbec5fbc2ea2003b52e76098c9ce2942675cca10 Mon Sep 17 00:00:00 2001 From: iridiumR Date: Sun, 18 Sep 2022 14:46:23 +0800 Subject: [PATCH] feat(builtin): add built-in command --- .gitignore | 2 ++ Makefile | 2 +- builtin.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ builtin.h | 12 ++++++++++++ exec.c | 31 +++++++++++++++++++++++++++++++ exec.h | 7 +++++++ line.c | 6 ++++++ line.h | 6 ++++++ loop.c | 9 +++++++-- loop.h | 6 ++++++ main.c | 10 ++++++++++ 11 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 builtin.c create mode 100644 builtin.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d99899 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +dish \ No newline at end of file diff --git a/Makefile b/Makefile index 99c6dfd..b536e4c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -OBJ=main.o line.o loop.o exec.o +OBJ=main.o line.o loop.o exec.o builtin.o CC=gcc CFLAGS= -O3 -Wall diff --git a/builtin.c b/builtin.c new file mode 100644 index 0000000..7e3e604 --- /dev/null +++ b/builtin.c @@ -0,0 +1,53 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:16:19 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:28:01 + */ +#include +#include +#include +#include + +int dish_cd(char **args); +int dish_help(char **args); +int dish_exit(char **args); + +char* builtin_cmd[] = { + "cd", + "help", + "exit" +}; + +int (*builtin_func[]) (char **) = { + &dish_cd, + &dish_help, + &dish_exit +}; + +int dish_cd(char **args) +{ + if (args[1] == NULL) { + fprintf(stderr, "dish: expected argument to \"cd\"\n"); + } else { + if (chdir(args[1]) != 0) { + perror("dish"); + } + } + return 0; +} + +int dish_help(char **args) +{ + fprintf(stdout, "Yet another Shell with C.\n"); + return 0; +} + +int dish_exit(char **args) +{ + exit(EXIT_SUCCESS); +} + +int getBuiltinNum() { + return sizeof(builtin_cmd) / sizeof(char *); +} \ No newline at end of file diff --git a/builtin.h b/builtin.h new file mode 100644 index 0000000..7092e79 --- /dev/null +++ b/builtin.h @@ -0,0 +1,12 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:15:44 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:41:38 + */ +#ifndef _BUILTIN_H_ +#define _BUILTIN_H_ + +int getBuiltinNum(); + +#endif \ No newline at end of file diff --git a/exec.c b/exec.c index aa1d644..ad5752d 100644 --- a/exec.c +++ b/exec.c @@ -1,7 +1,18 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:14:23 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:44:37 + */ #include #include #include +#include #include +#include "builtin.h" + +extern int (*builtin_func[]) (char **); +extern char* builtin_cmd[]; int forkExec(char **args) { pid_t pid; @@ -20,9 +31,29 @@ int forkExec(char **args) { /* fork error */ perror("dish"); } else { + extern char volatile isWaiting; + isWaiting = 1; /* parent process: wait child process*/ pid=wait(&status); + isWaiting = 0; } return WEXITSTATUS(status); } + +int commandExec(char **args) { + int i; + + if (args[0] == NULL) { + /* empty command */ + return 1; + } + + for (i = 0; i < getBuiltinNum(); i++) { + if (strcmp(args[0], builtin_cmd[i]) == 0) { + return (*builtin_func[i])(args); + } + } + + return forkExec(args); +} diff --git a/exec.h b/exec.h index 8b7f0ce..67b888b 100644 --- a/exec.h +++ b/exec.h @@ -1,4 +1,11 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:13:40 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:13:40 + */ #ifndef __EXEC_H__ #define __EXEC_H__ int forkExec(char **args); +int commandExec(char **args); #endif \ No newline at end of file diff --git a/line.c b/line.c index 0733a50..8df7b91 100644 --- a/line.c +++ b/line.c @@ -1,3 +1,9 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:14:05 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:14:05 + */ #include "line.h" #include #include diff --git a/line.h b/line.h index 0d5db46..846ba06 100644 --- a/line.h +++ b/line.h @@ -1,3 +1,9 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:14:28 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:14:28 + */ #ifndef _LINE_H_ #define _LINE_H_ #define LINE_BUF_SIZE 1024 diff --git a/loop.c b/loop.c index 8f1be78..f8f9cc7 100644 --- a/loop.c +++ b/loop.c @@ -1,3 +1,9 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:13:53 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:13:53 + */ #include #include #include @@ -9,11 +15,10 @@ int loop() { char *line; char **args; - int status = 1; printf("> "); line = readLine(); args = splitLine(line); - status = forkExec(args); + commandExec(args); free(line); free(args); return 0; diff --git a/loop.h b/loop.h index 56ec6fd..ddf39bd 100644 --- a/loop.h +++ b/loop.h @@ -1,3 +1,9 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:14:19 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:14:19 + */ #ifndef _LOOP_H_ #define _LOOP_H_ int loop(); diff --git a/main.c b/main.c index 7ca5c56..23b4e4b 100644 --- a/main.c +++ b/main.c @@ -1,12 +1,22 @@ +/* + * @Author: 1ridic + * @Date: 2022-09-18 14:13:59 + * @Last Modified by: 1ridic + * @Last Modified time: 2022-09-18 14:21:48 + */ #include #include #include #include #include "loop.h" +char volatile isWaiting = 0; void intHandler(int dummy) { + if (isWaiting) { + return; printf("\nSIGINT exit.\n"); exit(EXIT_FAILURE); + } } int main(int argc, char *argv[]) {