aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ground.h20
-rw-r--r--src/ground.cc103
-rw-r--r--src/main.cc91
3 files changed, 123 insertions, 91 deletions
diff --git a/include/ground.h b/include/ground.h
new file mode 100644
index 0000000..564e6ab
--- /dev/null
+++ b/include/ground.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "global.h"
+#include "util.h"
+#include "job.h"
+#include "handler.h"
+
+namespace ov4
+{
+
+void waitfg(pid_t pid);
+void do_bgfg(char **argv);
+
+
+}
diff --git a/src/ground.cc b/src/ground.cc
new file mode 100644
index 0000000..2047ebf
--- /dev/null
+++ b/src/ground.cc
@@ -0,0 +1,103 @@
+#include "ground.h"
+
+namespace ov4
+{
+
+using namespace std;
+
+/*
+ * waitfg - Block until process pid is no longer the foreground process
+ */
+void waitfg(pid_t pid)
+{
+ sigset_t prev_with_sigchld_unblocked;
+ // get current blocked signals
+ sigprocmask(0, nullptr, &prev_with_sigchld_unblocked);
+ sigdelset(&prev_with_sigchld_unblocked, SIGCHLD);
+ LOG << "waiting for pid "<< fgpid(jobs) << endl;
+ while (fgpid(jobs) != 0)
+ sigsuspend(&prev_with_sigchld_unblocked);
+ LOG << "finished fg " << endl;
+ return;
+}
+
+/*
+ * do_bgfg - Execute the builtin bg and fg commands
+ */
+void do_bgfg(char **argv)
+{
+ if ((strcmp(argv[0], "fg") == 0) || (strcmp(argv[0], "bg") == 0))
+ {
+ int x;
+ job_t *j = nullptr;
+ sigset_t prev;
+ if (argv[1] == nullptr)
+ {
+ cerr << ((strcmp(argv[0], "fg") == 0) ? "fg" : "bg") << " command requires PID or %jobid argument" << endl;
+ return;
+ }
+ if (argv[1][0] == '%') // jid provided
+ {
+ if (!isnum(&argv[1][1]))
+ {
+ cerr << ((strcmp(argv[0], "fg") == 0) ? "fg" : "bg") << ": argument must be a PID or %jobid" << endl;
+ return;
+ }
+ x = atoi(&argv[1][1]); // eat %
+ j = getjobjid(jobs, x);
+ if (j == nullptr)
+ {
+ cerr << argv[1] << ": No such job" << endl;
+ return;
+ }
+ } else { // pid
+ if (!isnum(&argv[1][0]))
+ {
+ cerr << ((strcmp(argv[0], "fg") == 0) ? "fg" : "bg") << ": argument must be a PID or %jobid" << endl;
+ return;
+ }
+ x = atoi(&argv[1][0]);
+ j = getjobpid(jobs, x);
+ if (j == nullptr)
+ {
+ cerr << "(" << argv[1] << "): No such process" << endl;
+ return;
+ }
+ }
+
+
+ block_all(&prev);
+ if (strcmp(argv[0], "fg") == 0) // fg
+ {
+ LOG << "fg" << endl;
+ j->state = FG;
+
+ sigset_t prev_with_sigchld_blocked = prev;
+ sigaddset(&prev_with_sigchld_blocked, SIGCHLD);
+ sigprocmask(SIG_SETMASK, &prev_with_sigchld_blocked, NULL);
+ if (kill(-(j->pid), SIGCONT) < 0)
+ {
+ cerr << "Cannot continue process " << j->pid;
+ sigprocmask(SIG_SETMASK, &prev, NULL);
+ return;
+ }
+
+ waitfg(j->pid);
+
+ sigprocmask(SIG_SETMASK, &prev, NULL);
+ } else // bg
+ {
+ LOG << "bg" << endl;
+ j->state = BG;
+ kill(-(j->pid), SIGCONT);
+ sigprocmask(SIG_SETMASK, &prev, NULL);
+ // cmdline has nerd '\n' at the end
+ // so just flush
+ cout << "[" << j->jid << "] (" << j->pid << ") " << j->cmdline << flush;
+ }
+ }
+ else
+ cerr << "not fg/bg" << endl;
+}
+
+}
diff --git a/src/main.cc b/src/main.cc
index e2aa815..7b7fafa 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -237,100 +237,9 @@ int builtin_cmd(char *c_str)
return 0; /* not a builtin command */
}
-/*
- * do_bgfg - Execute the builtin bg and fg commands
- */
-void do_bgfg(char **argv)
-{
- if ((strcmp(argv[0], "fg") == 0) || (strcmp(argv[0], "bg") == 0))
- {
- int x;
- job_t *j = nullptr;
- sigset_t prev;
- if (argv[1] == nullptr)
- {
- cerr << ((strcmp(argv[0], "fg") == 0) ? "fg" : "bg") << " command requires PID or %jobid argument" << endl;
- return;
- }
- if (argv[1][0] == '%') // jid provided
- {
- if (!isnum(&argv[1][1]))
- {
- cerr << ((strcmp(argv[0], "fg") == 0) ? "fg" : "bg") << ": argument must be a PID or %jobid" << endl;
- return;
- }
- x = atoi(&argv[1][1]); // eat %
- j = getjobjid(jobs, x);
- if (j == nullptr)
- {
- cerr << argv[1] << ": No such job" << endl;
- return;
- }
- } else { // pid
- if (!isnum(&argv[1][0]))
- {
- cerr << ((strcmp(argv[0], "fg") == 0) ? "fg" : "bg") << ": argument must be a PID or %jobid" << endl;
- return;
- }
- x = atoi(&argv[1][0]);
- j = getjobpid(jobs, x);
- if (j == nullptr)
- {
- cerr << "(" << argv[1] << "): No such process" << endl;
- return;
- }
- }
- block_all(&prev);
- if (strcmp(argv[0], "fg") == 0) // fg
- {
- LOG << "fg" << endl;
- j->state = FG;
-
- sigset_t prev_with_sigchld_blocked = prev;
- sigaddset(&prev_with_sigchld_blocked, SIGCHLD);
- sigprocmask(SIG_SETMASK, &prev_with_sigchld_blocked, NULL);
- if (kill(-(j->pid), SIGCONT) < 0)
- {
- cerr << "Cannot continue process " << j->pid;
- sigprocmask(SIG_SETMASK, &prev, NULL);
- return;
- }
- waitfg(j->pid);
-
- sigprocmask(SIG_SETMASK, &prev, NULL);
- } else // bg
- {
- LOG << "bg" << endl;
- j->state = BG;
- kill(-(j->pid), SIGCONT);
- sigprocmask(SIG_SETMASK, &prev, NULL);
- // cmdline has nerd '\n' at the end
- // so just flush
- cout << "[" << j->jid << "] (" << j->pid << ") " << j->cmdline << flush;
- }
- }
- else
- cerr << "not fg/bg" << endl;
-}
-
-/*
- * waitfg - Block until process pid is no longer the foreground process
- */
-void waitfg(pid_t pid)
-{
- sigset_t prev_with_sigchld_unblocked;
- // get current blocked signals
- sigprocmask(0, nullptr, &prev_with_sigchld_unblocked);
- sigdelset(&prev_with_sigchld_unblocked, SIGCHLD);
- LOG << "waiting for pid "<< fgpid(jobs) << endl;
- while (fgpid(jobs) != 0)
- sigsuspend(&prev_with_sigchld_unblocked);
- LOG << "finished fg " << endl;
- return;
-}