From b404880177a4eb9419a65fdf2536e42df36d524d Mon Sep 17 00:00:00 2001 From: _ov4 Date: Mon, 31 Aug 2026 07:29:46 +0000 Subject: eval --- src/eval.cc | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.cc | 98 +----------------------------------------------------------- src/parse.cc | 7 +++++ src/util.cc | 22 ++++++++++++-- 4 files changed, 109 insertions(+), 99 deletions(-) create mode 100644 src/eval.cc (limited to 'src') diff --git a/src/eval.cc b/src/eval.cc new file mode 100644 index 0000000..369e032 --- /dev/null +++ b/src/eval.cc @@ -0,0 +1,81 @@ +#include "eval.h" + +namespace ov4 +{ + +using namespace std; + +/* + * eval - Evaluate the command line that the user has just typed in + * + * If the user has requested a built-in command (quit, jobs, bg or fg) + * then execute it immediately. Otherwise, fork a child process and + * run the job in the context of the child. If the job is running in + * the foreground, wait for it to terminate and then return. Note: + * each child process must have a unique process group ID so that our + * background children don't receive SIGINT (SIGTSTP) from the kernel + * when we type ctrl-c (ctrl-z) at the keyboard. +*/ +void eval(char *cmdline) +{ + char arg[MAXARGS][MAXLINE]; + char *argv[MAXARGS]; + for (int i = 0 ; i < MAXARGS; i++) + { + argv[i] = &arg[i][0]; + } + int ground = parseline(cmdline, argv); + + if (argv[0] == nullptr) return; + + if (builtin_cmd(argv[0])) + { + LOG << "built-in" << endl; + if (strcmp(argv[0], "quit") == 0) builtin_command_quit(); + else if (strcmp(argv[0], "jobs") == 0) listjobs(jobs); + else if (strcmp(argv[0], "fg") == 0) do_bgfg(argv); + else if (strcmp(argv[0], "bg") == 0) do_bgfg(argv); + else cerr << "built-in but not supported" << endl; + return; + } + + sigset_t prev; + block_all(&prev); + + pid_t pid = fork(); + if (pid == 0) // child + { + sigprocmask(SIG_SETMASK, &prev, nullptr); + setpgid(0, 0); + + execve(argv[0], argv, environ); + + atomic_print(cmdline, true); + atomic_print(": Command not found\n"); + exit(-1); // if no command is found + } + + // parent + + if (!ground) // foreground + { + addjob(jobs, pid, FG, cmdline); + sigset_t prev_with_sigchld_blocked = prev; + sigaddset(&prev_with_sigchld_blocked, SIGCHLD); + sigprocmask(SIG_SETMASK, &prev_with_sigchld_blocked, NULL); + waitfg(pid); + sigprocmask(SIG_SETMASK, &prev, NULL); + } + else // background + { + addjob(jobs, pid, BG, cmdline); + sigprocmask(SIG_SETMASK, &prev, NULL); + cout << "[" << pid2jid(pid) << "] (" << pid << ") " << cmdline; + } + + + + return; +} + +} diff --git a/src/main.cc b/src/main.cc index 91448ff..4d89e6e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -21,6 +21,7 @@ #include "parse.h" #include "handler.h" #include "ground.h" +#include "eval.h" using namespace std; using namespace ov4; @@ -141,100 +142,8 @@ int main(int argc, char **argv) exit(0); /* control never reaches here */ } -/* - * eval - Evaluate the command line that the user has just typed in - * - * If the user has requested a built-in command (quit, jobs, bg or fg) - * then execute it immediately. Otherwise, fork a child process and - * run the job in the context of the child. If the job is running in - * the foreground, wait for it to terminate and then return. Note: - * each child process must have a unique process group ID so that our - * background children don't receive SIGINT (SIGTSTP) from the kernel - * when we type ctrl-c (ctrl-z) at the keyboard. -*/ -void eval(char *cmdline) -{ - char arg[MAXARGS][MAXLINE]; - char *argv[MAXARGS]; - for (int i = 0 ; i < MAXARGS; i++) - { - argv[i] = &arg[i][0]; - } - int ground = parseline(cmdline, argv); - - if (argv[0] == nullptr) return; - - if (builtin_cmd(argv[0])) - { - LOG << "built-in" << endl; - if (strcmp(argv[0], "quit") == 0) builtin_command_quit(); - else if (strcmp(argv[0], "jobs") == 0) listjobs(jobs); - else if (strcmp(argv[0], "fg") == 0) do_bgfg(argv); - else if (strcmp(argv[0], "bg") == 0) do_bgfg(argv); - else cerr << "built-in but not supported" << endl; - return; - } - - sigset_t prev; - block_all(&prev); - - pid_t pid = fork(); - if (pid == 0) // child - { - sigprocmask(SIG_SETMASK, &prev, nullptr); - setpgid(0, 0); - - execve(argv[0], argv, environ); - - atomic_print(cmdline, true); - atomic_print(": Command not found\n"); - exit(-1); // if no command is found - } - - // parent - - if (!ground) // foreground - { - addjob(jobs, pid, FG, cmdline); - sigset_t prev_with_sigchld_blocked = prev; - sigaddset(&prev_with_sigchld_blocked, SIGCHLD); - sigprocmask(SIG_SETMASK, &prev_with_sigchld_blocked, NULL); - waitfg(pid); - sigprocmask(SIG_SETMASK, &prev, NULL); - } - else // background - { - addjob(jobs, pid, BG, cmdline); - sigprocmask(SIG_SETMASK, &prev, NULL); - cout << "[" << pid2jid(pid) << "] (" << pid << ") " << cmdline; - } - - return; -} - -/* - * 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. - */ - - -/* - * builtin_cmd - If the user has typed a built-in command then execute - * it immediately. - */ -int builtin_cmd(char *c_str) -{ - string s(c_str); - for (auto c : builtin_cmd_list) - if (c == s) - return 1; - return 0; /* not a builtin command */ -} @@ -293,11 +202,6 @@ handler_t *Signal(int signum, handler_t *handler) } -void builtin_command_quit() -{ - exit(0); -} - diff --git a/src/parse.cc b/src/parse.cc index abb80d9..8480811 100644 --- a/src/parse.cc +++ b/src/parse.cc @@ -3,6 +3,13 @@ namespace ov4 { +/* + * 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 */ diff --git a/src/util.cc b/src/util.cc index bd516e8..9574ce6 100644 --- a/src/util.cc +++ b/src/util.cc @@ -3,8 +3,7 @@ namespace ov4 { -// constexpr int DECIMAL = 10; -// constexpr int LENGTH = 25; +using namespace std; void atomic_print(char *s, bool ignore_wrap) { @@ -97,4 +96,23 @@ char *itoa(int num, char* str, int base) return str; } +/* + * builtin_cmd - If the user has typed a built-in command then execute + * it immediately. + */ +int builtin_cmd(char *c_str) +{ + string s(c_str); + for (auto c : builtin_cmd_list) + if (c == s) + return 1; + return 0; /* not a builtin command */ +} + +void builtin_command_quit() +{ + exit(0); +} + + } -- cgit v1.3.1-4-g156e