aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/job.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/rc/job.c')
-rw-r--r--src/cmd/rc/job.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/cmd/rc/job.c b/src/cmd/rc/job.c
new file mode 100644
index 0000000..1587951
--- /dev/null
+++ b/src/cmd/rc/job.c
@@ -0,0 +1,91 @@
+#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->link)
+ ;
+
+ 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 *job)
+{
+ int i;
+ job->wait.status = Prun;
+ for(i=0; i < job->wait.len; i++){
+ if(job->wait.on[i].status == Pstop)
+ job->wait.on[i].status = Prun;
+ }
+
+ tcsetpgrp(0, job->pgid);
+}
+
+void
+foreground(Thread *job, int now)
+{
+ Thread *caller = job->caller;
+ if(now){
+ if(kill(-job->pgid, SIGCONT) < 0)
+ perror("kill[SIGCONT]");
+ }
+
+ waitall(job);
+ /*
+ * reset state if we have a caller
+ * otherwise we will exit anyways
+ */
+ if(caller && caller->flag.user){
+ tcsetpgrp(0, caller->pid);
+ job->flag.user = 1;
+ }
+}
+
+void
+addjob(Thread *job)
+{
+ job->link = shell.jobs;
+ shell.jobs = job;
+ job->wait.status = Prun;
+}
+
+void
+deljob(Thread *job)
+{
+ Thread **jp;
+
+ for(jp = &shell.jobs; *jp && *jp != job; jp = &(*jp)->link)
+ ;
+
+ *jp = job->link;
+}