Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}
Beispiel #5
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;
}
Beispiel #6
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();
}