int _ajax_sesinit() { capability owner; /* Current owner; may be session svr private */ capability self; /* This process */ capability *session; /* Most specific session svr cap */ capability *tty; /* TTY (stdin) */ int pid; /* Process ID if known */ int err; MU_LOCK(&mu); if (!_ajax_sesinited) { session = getcap("_SESSION"); if (session == NULL) { MU_UNLOCK(&mu); _ajax_puts( "Ajax (init): can't find _SESSION in cap env"); ERR(EIO, "sesinit: no _SESSION in cap env"); } if (_ajax_getowner(&owner) != 0) { MU_UNLOCK(&mu); return -1; /* Can't find owner capability */ } if (getinfo(&self, NILPD, 0) < 0) { MU_UNLOCK(&mu); ERR(EIO, "sesinit: getinfo failed"); } if (PORTCMP(&owner.cap_port, &session->cap_port)) { /* Session svr already owns us */ session = &owner; pid = prv_number(&owner.cap_priv); } else { /* Owner is not the session svr */ pid = 0; } if ((err = ses_init(session, &self, &_ajax_session)) < 0) { MU_UNLOCK(&mu); _ajax_putnum("Ajax (init): session init failed, error", err); ERR(EIO, "sesinit: ses_init failed"); } if (pid == 0) { /* Arrange for tty interrupts to go to the * session server. */ if ((tty = getcap("TTY")) != NULL) { (void) ttq_intcap(tty, &_ajax_session); } } _ajax_sesinited = 1; } MU_UNLOCK(&mu); return 0; }
/* * Read system call. */ int anp_read(int fd,char *buf,unsigned int nbytes) { register struct socket *sock; struct uio auio; struct iovec aiov; long cnt, error = 0; MU_LOCK(kern_lock_p); sock=anp_fdfind(fd); aiov.iov_base = (caddr_t) buf; aiov.iov_len = nbytes; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_resid = nbytes; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_USERSPACE; cnt = nbytes; if (error = (soo_read)(sock, &auio)) if (auio.uio_resid != cnt && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; cnt -= auio.uio_resid; anp_errno=error; MU_UNLOCK(kern_lock_p); if (anp_errno!=0) { return -1; } else { return cnt; } }
/* close system call: */ int anp_close(int fd) { struct socket *sock; MU_LOCK(kern_lock_p); sock=anp_fdfind(fd); soclose(sock); anp_fdfree(fd); MU_UNLOCK(kern_lock_p); return 0; }
void *spipe_input_thread(void *arg) { #define BUFSIZE 256 unsigned char buf[BUFSIZE]; int i,nbytes; while (1) { if ((nbytes=read(in_fd,buf,BUFSIZE)) < 0) { perror("read"); exit(1); } MU_LOCK(&kern_lock); for (i=0; i < nbytes; i++) { slinput((int) buf[i], arg); } MU_UNLOCK(&kern_lock); } }
/* * Write system call */ int anp_write(int fd,char *buf,unsigned int nbytes) { struct socket *sock; struct uio auio; struct iovec aiov; long cnt, error = 0; MU_LOCK(kern_lock_p); sock=anp_fdfind(fd); aiov.iov_base = (caddr_t) buf; aiov.iov_len = nbytes; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_resid = nbytes; auio.uio_rw = UIO_WRITE; auio.uio_segflg = UIO_USERSPACE; cnt = nbytes; if (error = soo_write(sock, &auio)) { if (auio.uio_resid != cnt && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; #ifdef NOPE /* signals not supported */ if (error == EPIPE) psignal(p, SIGPIPE); #endif } cnt -= auio.uio_resid; anp_errno=error; MU_UNLOCK(kern_lock_p); if (anp_errno!=0) { return -1; } else { return cnt; } }
/* * Ioctl system call */ int anp_ioctl(int fd,int ucom,caddr_t udata) { struct socket *sock; register int com, error; register u_int size; caddr_t data, memp; int tmp; #define STK_PARAMS 128 char stkbuf[STK_PARAMS]; MU_LOCK(kern_lock_p); sock=anp_fdfind(fd); com=ucom; /* AC: since we don't support exec() in sim. environment, we don't support * these ioctl's either... */ #ifdef NOPE switch (com = ucom) { case FIONCLEX: fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; MU_UNLOCK(kern_lock_p); return (0); case FIOCLEX: fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; MU_UNLOCK(kern_lock_p); return (0); } #endif /* * Interpret high order word to find amount of data to be * copied to/from the user's address space. */ size = IOCPARM_LEN(com); if (size > IOCPARM_MAX) { anp_errno=ENOTTY; MU_UNLOCK(kern_lock_p); return -1; } memp = NULL; if (size > sizeof (stkbuf)) { memp = (caddr_t)anp_sys_malloc((u_long)size, M_IOCTLOPS, M_WAITOK); data = memp; } else data = stkbuf; if (com&IOC_IN) { if (size) { error = copyin(udata, data, (u_int)size); if (error) { if (memp) anp_sys_free(memp, M_IOCTLOPS); anp_errno=error; MU_UNLOCK(kern_lock_p); return -1; } } else *(caddr_t *)data = udata; } else if ((com&IOC_OUT) && size) /* * Zero the buffer so the user always * gets back something deterministic. */ bzero(data, size); else if (com&IOC_VOID) *(caddr_t *)data = udata; switch (com) { case FIONBIO: case FIOASYNC: tmp = *((int *) data); error = (soo_ioctl)(sock, com, (caddr_t)&tmp); break; #ifdef NOPE case FIOSETOWN: tmp = *((int *)data); if (fp->f_type == DTYPE_SOCKET) { ((struct socket *)fp->f_data)->so_pgid = tmp; error = 0; break; } if (tmp <= 0) { tmp = -tmp; } else { struct proc *p1 = pfind(tmp); if (p1 == 0) { error = ESRCH; break; } tmp = p1->p_pgrp->pg_id; } error = (*fp->f_ops->fo_ioctl) (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p); break; case FIOGETOWN: if (fp->f_type == DTYPE_SOCKET) { error = 0; *(int *)data = ((struct socket *)fp->f_data)->so_pgid; break; } error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p); *(int *)data = -*(int *)data; break; #endif default: error = soo_ioctl(sock, com, data); /* * Copy any data to user, size was * already set and checked above. */ if (error == 0 && (com&IOC_OUT) && size) error = copyout(data, udata, (u_int)size); break; } if (memp) anp_sys_free(memp, M_IOCTLOPS); anp_errno=error; MU_UNLOCK(kern_lock_p); if (anp_errno!=0) { return -1; } else { return 0; } }