aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/job.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/job.c')
-rw-r--r--sys/cmd/rc/job.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/sys/cmd/rc/job.c b/sys/cmd/rc/job.c
new file mode 100644
index 0000000..779ce6c
--- /dev/null
+++ b/sys/cmd/rc/job.c
@@ -0,0 +1,82 @@
+#include "rc.h"
+
+#include <signal.h>
+#include <termios.h>
+
+// -----------------------------------------------------------------------
+// exports
+
+Thread *
+getjob(int pid, int *index)
+{
+ int i;
+ Thread *job;
+ for(i=0,job=shell.jobs; job && job->pid != pid; i++, job=job->next)
+ ;
+
+ return job;
+}
+
+void
+report(Thread *job, int index)
+{
+ switch(job->wait.status){
+ case PDone:
+ print(shell.err, "job %d [%d]: done\n", index, job->pid);
+ break;
+ case PStop:
+ print(shell.err, "job %d [%d]: suspended\n", index, job->pid);
+ break;
+ case PAgain:
+ print(shell.err, "job %d [%d]: continued\n", index, job->pid);
+ break;
+ case PRun:
+ print(shell.err, "job %d [%d]: running\n", index, job->pid);
+ break;
+ default:
+ fatal("bad wait status: %d\n", job->wait.status);
+ }
+}
+
+void
+wakeup(Thread *t)
+{
+ int i;
+ t->wait.status = PRun;
+ for(i=0; i < t->wait.len; i++){
+ if(t->wait.on[i].status == PStop)
+ t->wait.on[i].status = PRun;
+ }
+}
+
+void
+foreground(Thread *job, int signal)
+{
+ tcsetpgrp(0, job->pgid);
+ if(signal){
+ if(kill(-job->pgid, SIGCONT) < 0)
+ perror("kill[SIGCONT]");
+ }
+
+ waitall(job);
+
+ tcsetpgrp(0, shell.pid);
+}
+
+void
+addjob(Thread *job)
+{
+ job->next = shell.jobs;
+ shell.jobs = job;
+}
+
+void
+deljob(Thread *job)
+{
+ Thread **jp;
+
+ for(jp = &shell.jobs; *jp && *jp != job; jp = &(*jp)->next)
+ ;
+
+ *jp = job->next;
+}