arg_t _waitpid(void) { ptptr p; int retval; if (statloc && !valaddr((char *) statloc, sizeof(int))) { udata.u_error = EFAULT; return (-1); } /* FIXME: move this scan into the main loop and also error on a complete loop finding no matchi for pid */ /* See if we have any children. */ for (p = ptab; p < ptab_end; ++p) { if (p->p_status && p->p_pptr == udata.u_ptab && p != udata.u_ptab) goto ok; } udata.u_error = ECHILD; return (-1); ok: if (pid == 0) pid = -udata.u_ptab->p_pgrp; /* Search for an exited child; */ for (;;) { chksigs(); if (udata.u_cursig) { udata.u_error = EINTR; return -1; } for (p = ptab; p < ptab_end; ++p) { if (p->p_status == P_ZOMBIE && p->p_pptr == udata.u_ptab) { if (pid == -1 || p->p_pid == pid || p->p_pgrp == -pid) { if (statloc) uputw(p->p_exitval, statloc); retval = p->p_pid; p->p_status = P_EMPTY; /* Add in child's time info. It was stored on top */ /* of p_priority in the childs process table entry. */ udata.u_cutime += ((clock_t *)p->p_priority)[0]; udata.u_cstime += ((clock_t *)p->p_priority)[1]; return retval; } } } /* Nothing yet, so wait */ if (options & WNOHANG) break; psleep(udata.u_ptab); } udata.u_error = EINTR; return -1; }
static int iopoll(int sofar) { /* Ought to be a core helper for this lot ? */ if (need_reschedule()) _sched_yield(); if (chksigs()) { if (sofar) return sofar; udata.u_error = EINTR; return -1; } return 0; }
int psleep_flags(void *p, unsigned char flags) { if (flags & O_NDELAY) { udata.u_error = EAGAIN; return -1; } psleep(p); if (chksigs()) { udata.u_error = EINTR; return -1; } return 0; }
static uint8_t iopoll(void) { /* Ought to be a core helper for this lot ? */ if (need_reschedule()) _sched_yield(); if (chksigs()) { if (!udata.u_done) { udata.u_error = EINTR; udata.u_done = (usize_t)-1; } return 1; } return 0; }
int psleep_flags_io(void *p, unsigned char flags) { if (flags & O_NDELAY) { if (!udata.u_done) { udata.u_done = (usize_t)-1; udata.u_error = EAGAIN; } return -1; } psleep(p); if (chksigs()) { if (!udata.u_done) { udata.u_done = (usize_t)-1; udata.u_error = EINTR; } return -1; } return 0; }
// Fuzix system call handler // we arrive here from syscall.s with the kernel paged in, using the kernel stack, interrupts enabled. void unix_syscall(void) { // NO LOCAL VARIABLES PLEASE udata.u_error = 0; /* Fuzix saves the Stack Pointer and arguments in the * Assembly Language Function handler in lowlevel.s */ if (udata.u_callno >= FUZIX_SYSCALL_COUNT) { udata.u_error = EINVAL; } else { #ifdef DEBUG kprintf("\t\tpid %d: syscall %d\t%s(%x, %x, %x)\n", udata.u_ptab->p_pid, udata.u_callno, syscall_name[udata.u_callno], udata.u_argn, udata.u_argn1, udata.u_argn2); #endif // dispatch system call udata.u_retval = (*syscall_dispatch[udata.u_callno]) (); #ifdef DEBUG kprintf("\t\t\tpid %d: ret syscall %d, ret %x err %d\n", udata.u_ptab->p_pid, udata.u_callno, udata.u_retval, udata.u_error); #endif } udata.u_ptab->p_timeout = 0; chksigs(); di(); if (runticks >= udata.u_ptab->p_priority && nready > 1) { /* Time to switch out? - we may have overstayed our welcome inside a syscall so switch straight afterwards */ udata.u_ptab->p_status = P_READY; switchout(); } ei(); }