aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-08-31 07:29:46 +0000
committer_ov4 <ov4@ov4.org>2026-08-31 07:29:46 +0000
commitb404880177a4eb9419a65fdf2536e42df36d524d (patch)
treebb7bd6e85414add09297feafa1b67ebcbb796980
parent60c1851b4ab92a5687af16ef566486e48813babc (diff)
eval
-rw-r--r--include/eval.h20
-rw-r--r--include/util.h4
-rw-r--r--src/eval.cc81
-rw-r--r--src/main.cc98
-rw-r--r--src/parse.cc7
-rw-r--r--src/util.cc22
6 files changed, 131 insertions, 101 deletions
diff --git a/include/eval.h b/include/eval.h
new file mode 100644
index 0000000..6b0d1fa
--- /dev/null
+++ b/include/eval.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "global.h"
+#include "util.h"
+#include "job.h"
+#include "ground.h"
+#include "parse.h"
diff --git a/include/util.h b/include/util.h
index dd51fff..bab7738 100644
--- a/include/util.h
+++ b/include/util.h
@@ -26,6 +26,8 @@ void atomic_debug(int x);
bool isnum(char *s);
void reverse(char str[], int length);
char *itoa(int num, char* str, int base);
+int builtin_cmd(char *c_str);
+void builtin_command_quit();
constexpr bool GLOBAL_DEBUG = true;
struct LogVoidify { void operator&(std::ostream&) const {} };
@@ -33,6 +35,4 @@ struct LogVoidify { void operator&(std::ostream&) const {} };
constexpr int DECIMAL = 10;
constexpr int LENGTH = 32;
-
-
}
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);
+}
+
+
}