arg_t _signal(void) { int16_t retval; irqflags_t irq; if (sig < 1 || sig >= NSIGS) { udata.u_error = EINVAL; goto nogood; } irq = di(); if (func == SIG_IGN) { if (sig != SIGKILL && sig != SIGSTOP) udata.u_ptab->p_ignored |= sigmask(sig); } else { if (func != SIG_DFL && !valaddr((char *) func, 1)) { udata.u_error = EFAULT; goto nogood; } udata.u_ptab->p_ignored &= ~sigmask(sig); } retval = (arg_t) udata.u_sigvec[sig]; if (sig != SIGKILL && sig != SIGSTOP) udata.u_sigvec[sig] = func; irqrestore(irq); return (retval); nogood: return (-1); }
int uputc(uint16_t value, void *user) { if (!valaddr(user, 1)) return -1; /* u16_t so we don't get wacky 8bit stack games on SDCC */ return _uputc(value,user); }
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; }
/* ugets is a bit odd - we don't know the length of the passed string so we trim to the end of the allowed memory and if we don't find a \0 in time we error */ int ugets(const void *user, void *dest, usize_t maxlen) { int ret; maxlen = valaddr(user, maxlen); if (!maxlen) return -1; ret = _ugets(user, dest, maxlen); if (ret == -1) udata.u_error = EFAULT; return ret; }
uint32_t ugetl(void *uaddr, int *err) { if (!valaddr(uaddr, 4)) { if (err) *err = -1; return -1; } if (err) *err = 0; return *(uint32_t *)uaddr; }
int16_t _write(void) { inoptr ino; uint8_t flag; if (!valaddr(buf, nbytes)) return -1; /* Set up u_base, u_offset, ino; check permissions, file num. */ if ((ino = rwsetup(false, &flag)) == NULLINODE) return (-1); /* bomb out if error */ writei(ino, flag); updoff(); return (udata.u_count); }
arg_t _read(void) { inoptr ino; uint8_t flag; if (!nbytes) return 0; if (!valaddr(buf, nbytes)) return -1; /* Set up u_base, u_offset, ino; check permissions, file num. */ if ((ino = rwsetup(true, &flag)) == NULLINODE) return -1; /* bomb out if error */ readi(ino, flag); updoff(); return (udata.u_count); }
int16_t _utime(void) { inoptr ino; time_t t[2]; if (!valaddr(buf, 2 * sizeof(time_t))) return (-1); if (!(ino = n_open(file, NULLINOPTR))) return (-1); if (ino->c_node.i_uid != udata.u_euid && esuper()) { i_deref(ino); return (-1); } uget(buf, t, 2 * sizeof(time_t)); /* FIXME: needs updating once we pack top bits elsewhere in the inode */ ino->c_node.i_atime = t[0]; ino->c_node.i_mtime = t[1]; setftime(ino, C_TIME); i_deref(ino); return (0); }
arg_t _utime(void) { inoptr ino; time_t t[2]; if (!(ino = n_open(file, NULLINOPTR))) return (-1); if (ino->c_flags & CRDONLY) { udata.u_error = EROFS; goto out2; } /* Special case in the Unix API - NULL means now */ if (buf) { if (ino->c_node.i_uid != udata.u_euid && esuper()) goto out; if (!valaddr(buf, 2 * sizeof(time_t))) goto out2; uget(buf, t, 2 * sizeof(time_t)); } else { if (!(getperm(ino) & OTH_WR)) goto out; rdtime(&t[0]); memcpy(&t[1], &t[0], sizeof(t[1])); } /* FIXME: needs updating once we pack top bits elsewhere in the inode */ ino->c_node.i_atime = t[0].low; ino->c_node.i_mtime = t[1].low; setftime(ino, C_TIME); i_deref(ino); return (0); out: udata.u_error = EPERM; out2: i_deref(ino); return -1; }
void f(void) { statloc && !valaddr((char *) statloc, sizeof(int)); }
int uzero(void *user, usize_t count) { if (!valaddr(user, count)) return -1; return _uzero(user,count); }
int uputw(uint16_t value, void *user) { if (!valaddr(user, 2)) return -1; return _uputw(value,user); }
uint16_t ugetw(const void *user) { if (!valaddr(user, 2)) return -1; return _ugetw(user); }
int16_t ugetc(const void *user) { if (!valaddr(user, 1)) return -1; return _ugetc(user); }
int uget(const void *user, void *dst, usize_t count) { if (!valaddr(user,count)) return -1; return _uget(user,dst,count); }
uint16_t ugetw(const void *user) { if (!valaddr(user, 2)) return -1; #ifdef MISALIGNED if (MISALIGNED(user, 2)) }
int uputl(uint32_t val, void *uaddr) { if (!valaddr(uaddr, 4)) return -1; return *(uint32_t *)uaddr; }
int uput(const void *source, void *user, usize_t count) { if (!valaddr(user, count)) return -1; return _uput(source,user,count); }