aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/wait.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/wait.c')
-rw-r--r--sys/cmd/rc/wait.c247
1 files changed, 0 insertions, 247 deletions
diff --git a/sys/cmd/rc/wait.c b/sys/cmd/rc/wait.c
deleted file mode 100644
index 911601c..0000000
--- a/sys/cmd/rc/wait.c
+++ /dev/null
@@ -1,247 +0,0 @@
-#include "rc.h"
-
-#include <sys/wait.h>
-
-// -----------------------------------------------------------------------
-// globals
-
-struct WaitMsg
-{
- int pid;
- int type;
- ulong time[3];
- int status;
-};
-
-// -----------------------------------------------------------------------
-// internal
-
-static
-int
-await(int pid4, int opt, struct WaitMsg *msg)
-{
- int pid, status, core;
- struct rusage ru;
- ulong u, s;
-
- /* event loop */
- for(;;){
- if((pid = wait4(pid4, &status, opt, &ru)) <= 0){
- if(errno == ECHILD){
- msg->pid = -1;
- return 1;
- }
- msg->pid = 0;
- perror("failed wait4");
- return 0;
- }
-
- u = ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000);
- s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000);
-
- if(WIFEXITED(status)){
- msg->pid = pid;
- msg->time[0] = u;
- msg->time[1] = s;
- msg->time[2] = u+s;
- msg->status = WEXITSTATUS(status);
- msg->type = Pdone;
-
- return 1;
- }
-
- if(WIFSIGNALED(status)){
- msg->pid = pid;
- msg->time[0] = u;
- msg->time[1] = s;
- msg->time[2] = u+s;
- msg->status = WTERMSIG(status);
- msg->type = Psig;
-
- return 1;
- }
-
- if(WIFSTOPPED(status)){
- msg->pid = pid;
- msg->time[0] = u;
- msg->time[1] = s;
- msg->time[2] = u+s;
- msg->status = WSTOPSIG(status);
- msg->type = Pstop;
-
- return 1;
- }
- }
-}
-
-static
-int
-shouldwait(Thread *job)
-{
- int i;
-
- for(i=0; i<job->wait.len; i++){
- if(job->wait.on[i].status == Prun)
- return 1;
- }
-
- return 0;
-}
-
-static inline
-void
-notify(Thread *job, struct WaitMsg msg)
-{
- int i;
- for(i=0; i < job->wait.len; i++){
- if(job->wait.on[i].pid == msg.pid){
- job->status = msg.status;
- switch(msg.type){
- case Pstop:
- print(shell.err, "%d: suspended\n", msg.pid);
- job->wait.status = Pstop;
- job->wait.on[i].status = Pstop;
- break;
-
- case Psig:
- print(shell.err, "%d: terminated by signal %d\n", msg.pid, msg.status);
- /* fallthrough */
- case Pdone:
- job->wait.on[i].status = Pdone;
- delwait(job, msg.pid);
- if(!job->wait.len)
- job->wait.status = Pdone;
- break;
-
- default:
- fatal("%d: unrecognized message type %d\n", msg.pid, msg.type);
- }
- break;
- }
- }
-}
-
-// -----------------------------------------------------------------------
-// exported
-
-void
-clearwait(Thread *job)
-{
- job->wait.len = 0;
-}
-
-int
-havewait(Thread *job, int pid)
-{
- int i;
-
- for(i=0; i<job->wait.len; i++)
- if(job->wait.on[i].pid == pid)
- return 1;
- return 0;
-}
-
-void
-addwait(Thread *job, int pid)
-{
- if(job->wait.len == job->wait.cap){
- job->wait.cap = job->wait.cap + 2;
- job->wait.on = erealloc(job->wait.on, job->wait.cap*sizeof(*job->wait.on));
- }
-
- job->wait.on[job->wait.len++] = (struct WaitItem){.pid=pid, .status=Prun};
-}
-
-void
-delwait(Thread *job, int pid)
-{
- int r, w;
-
- for(r=w=0; r < job->wait.len; r++){
- if(job->wait.on[r].pid != pid)
- job->wait.on[w++].pid = job->wait.on[r].pid;
- }
- job->wait.len = w;
-}
-
-int
-waitall(Thread *job)
-{
- int i;
- Thread *t;
- struct WaitMsg msg;
-
- while(shouldwait(job) && await(-job->pgid, WUNTRACED, &msg)){
- switch(msg.pid){
- case 0: // error
- perror("wait job");
- return 0;
- case -1: // no children: assume they have exited
- job->wait.status = Pdone;
- clearwait(job);
- return 1;
- default:
- ;
- }
-
- notify(job, msg);
- }
- return 1;
-}
-
-int
-waitfor(Thread *job, int pid)
-{
- int i;
- Thread *t;
- struct WaitMsg msg;
-
- while(shouldwait(job) && await(-job->pgid, WUNTRACED, &msg)){
- switch(msg.pid){
- case 0: // error
- perror("wait for");
- return 0;
- case -1: // no children: assume they have exited
- job->wait.status = Pdone;
- clearwait(job);
- return 1;
- default:
- ;
- }
-
- notify(job, msg);
- /* allow for an early exit */
- if(msg.pid == pid)
- return 1;
- }
- return 1;
-
-}
-
-void
-killzombies(void)
-{
- Thread *job;
- int index, status, pid;
-
- while((pid=waitpid(-1, &status, WNOHANG))>0){
- print(shell.err, "found zombie pid %d\n", pid);
- flush(shell.err);
-
- job = getjob(pid, &index);
- if(!job)
- perror("invalid pid");
-
- if(WIFEXITED(status))
- job->wait.status = Pdone;
- if(WIFSTOPPED(status))
- job->wait.status = Pstop;
- if(WIFCONTINUED(status))
- job->wait.status = Pagain;
-
- if(job->wait.status == Pdone){
- report(job,index);
- deljob(job);
- }
- }
-}