diff options
| -rw-r--r-- | tsh.cc | 49 | ||||
| -rw-r--r-- | util.h | 14 |
2 files changed, 44 insertions, 19 deletions
@@ -19,6 +19,7 @@ using namespace std; using ov4::atomic_print; +using ov4::atomic_debug; using ov4::isnum; /* Misc manifest constants */ @@ -193,8 +194,7 @@ void eval(char *cmdline) if (builtin_cmd(argv[0])) { - // TODO - cout << "built-in" << endl; + 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); @@ -249,7 +249,7 @@ void eval(char *cmdline) addjob(jobs, pid, BG, cmdline); // unblock to oldest sigprocmask(SIG_SETMASK, &prev, NULL); - cout << "[" << pid2jid(pid) << "] (" << pid << ") " << cmdline << endl; + cout << "[" << pid2jid(pid) << "] (" << pid << ") " << cmdline; } @@ -338,6 +338,11 @@ void do_bgfg(char **argv) 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])) @@ -350,9 +355,10 @@ void do_bgfg(char **argv) if (j == nullptr) { cerr << argv[1] << ": No such job" << endl; + return; } } else { // pid - if (!isnum(&argv[1][1])) + if (!isnum(&argv[1][0])) { cerr << ((strcmp(argv[0], "fg") == 0) ? "fg" : "bg") << ": argument must be a PID or %jobid" << endl; return; @@ -361,7 +367,7 @@ void do_bgfg(char **argv) j = getjobpid(jobs, x); if (j == nullptr) { - cerr << argv[1] << ": No such process" << endl; + cerr << "(" << argv[1] << "): No such process" << endl; return; } } @@ -396,11 +402,11 @@ void waitfg(pid_t pid) sigprocmask(0, NULL, &prev); // remove SIGCHILD sigdelset(&prev, SIGCHLD); - clog << "waiting for pid "<< fgpid(jobs) << endl; + LOG << "waiting for pid "<< fgpid(jobs) << endl; job_t *j = getjobpid(jobs, pid); while (fgpid(jobs) != 0) sigsuspend(&prev); - clog << "finished fg " << endl; + LOG << "finished fg " << endl; if ((j->state == ST)) { cout << "[" << j->jid << "] (" << pid << ") Stopped " << j->cmdline << endl; @@ -423,15 +429,27 @@ void sigchld_handler(int sig) { int errno_backup = errno; int status, pid; - atomic_print("SIGCHLD\n"); + atomic_debug("SIGCHLD\n"); - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { - atomic_print("pid: "); - atomic_print(pid); - atomic_print("\n"); + if (WIFSTOPPED(status)) + { + atomic_debug("suspended pid: "); + atomic_debug(pid); + atomic_debug("\n"); + sigset_t prev; + block_all(&prev); + job_suspend(jobs, pid); + sigprocmask(SIG_SETMASK, &prev, nullptr); + return; + } + atomic_debug("terminated pid: "); + atomic_debug(pid); + sigset_t prev; + block_all(&prev); deletejob(jobs, pid); - atomic_print(pid); + sigprocmask(SIG_SETMASK, &prev, nullptr); } @@ -465,11 +483,6 @@ void sigtstp_handler(int sig) if (pid != 0) { kill(-pid, SIGTSTP); - sigset_t mask_all, prev; - sigfillset(&mask_all); - sigprocmask(SIG_SETMASK, &mask_all, &prev); - job_suspend(jobs, pid); - sigprocmask(SIG_SETMASK, &prev, NULL); } return; } @@ -19,12 +19,14 @@ namespace ov4 { void atomic_print(char *s); void atomic_print(int x); +void atomic_debug(char *s); +void atomic_debug(int x); bool isnum(char *s); void reverse(char str[], int length); char* itoa(int num, char* str, int base); constexpr bool GLOBAL_DEBUG = true; -bool DEBUG = true; // verbose mode, can be enabled on demand using something like -v +bool DEBUG = false; // verbose mode, can be enabled on demand using something like -v struct LogVoidify { void operator&(std::ostream&) const {} }; const int DECIMAL = 10; @@ -55,6 +57,16 @@ void reverse(char str[], int length) } } +void atomic_debug(char *s) +{ + if (DEBUG && GLOBAL_DEBUG) atomic_print(s); +} + +void atomic_debug(int x) +{ + if (DEBUG && GLOBAL_DEBUG) atomic_print(x); +} + bool isnum(char *s) { for (int i = 0; s[i] != 0; i++) |
