123375Smckusick /* 247540Skarels * Copyright (c) 1982, 1986, 1991 Regents of the University of California. 352497Storek * All rights reserved. 423375Smckusick * 547540Skarels * %sccs.include.redist.c% 647540Skarels * 7*56517Sbostic * @(#)kern_subr.c 7.11 (Berkeley) 10/11/92 823375Smckusick */ 912792Ssam 10*56517Sbostic #include <sys/param.h> 11*56517Sbostic #include <sys/systm.h> 12*56517Sbostic #include <sys/proc.h> 13*56517Sbostic #include <sys/malloc.h> 1412792Ssam 1537728Smckusick uiomove(cp, n, uio) 1612792Ssam register caddr_t cp; 1712792Ssam register int n; 1812792Ssam register struct uio *uio; 1912792Ssam { 2012792Ssam register struct iovec *iov; 2112792Ssam u_int cnt; 2212792Ssam int error = 0; 2312792Ssam 2448016Smckusick #ifdef DIAGNOSTIC 2537728Smckusick if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) 2637728Smckusick panic("uiomove: mode"); 2748016Smckusick if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc) 2848016Smckusick panic("uiomove proc"); 2948016Smckusick #endif 3012792Ssam while (n > 0 && uio->uio_resid) { 3112792Ssam iov = uio->uio_iov; 3212792Ssam cnt = iov->iov_len; 3312792Ssam if (cnt == 0) { 3412792Ssam uio->uio_iov++; 3512792Ssam uio->uio_iovcnt--; 3612792Ssam continue; 3712792Ssam } 3812792Ssam if (cnt > n) 3912792Ssam cnt = n; 4012792Ssam switch (uio->uio_segflg) { 4112792Ssam 4216704Smckusick case UIO_USERSPACE: 4316704Smckusick case UIO_USERISPACE: 4437728Smckusick if (uio->uio_rw == UIO_READ) 4512792Ssam error = copyout(cp, iov->iov_base, cnt); 4612792Ssam else 4712792Ssam error = copyin(iov->iov_base, cp, cnt); 4812792Ssam if (error) 4912792Ssam return (error); 5012792Ssam break; 5112792Ssam 5216704Smckusick case UIO_SYSSPACE: 5337728Smckusick if (uio->uio_rw == UIO_READ) 5412792Ssam bcopy((caddr_t)cp, iov->iov_base, cnt); 5512792Ssam else 5612792Ssam bcopy(iov->iov_base, (caddr_t)cp, cnt); 5712792Ssam break; 5812792Ssam } 5912792Ssam iov->iov_base += cnt; 6012792Ssam iov->iov_len -= cnt; 6112792Ssam uio->uio_resid -= cnt; 6212792Ssam uio->uio_offset += cnt; 6312792Ssam cp += cnt; 6412792Ssam n -= cnt; 6512792Ssam } 6612792Ssam return (error); 6712792Ssam } 6812792Ssam 6912792Ssam /* 7012792Ssam * Give next character to user as result of read. 7112792Ssam */ 7212792Ssam ureadc(c, uio) 7312792Ssam register int c; 7412792Ssam register struct uio *uio; 7512792Ssam { 7612792Ssam register struct iovec *iov; 7712792Ssam 7812792Ssam again: 7912792Ssam if (uio->uio_iovcnt == 0) 8012792Ssam panic("ureadc"); 8112792Ssam iov = uio->uio_iov; 8212792Ssam if (iov->iov_len <= 0 || uio->uio_resid <= 0) { 8312792Ssam uio->uio_iovcnt--; 8412792Ssam uio->uio_iov++; 8512792Ssam goto again; 8612792Ssam } 8712792Ssam switch (uio->uio_segflg) { 8812792Ssam 8916704Smckusick case UIO_USERSPACE: 9012792Ssam if (subyte(iov->iov_base, c) < 0) 9112792Ssam return (EFAULT); 9212792Ssam break; 9312792Ssam 9416704Smckusick case UIO_SYSSPACE: 9512792Ssam *iov->iov_base = c; 9612792Ssam break; 9712792Ssam 9816704Smckusick case UIO_USERISPACE: 9912792Ssam if (suibyte(iov->iov_base, c) < 0) 10012792Ssam return (EFAULT); 10112792Ssam break; 10212792Ssam } 10312792Ssam iov->iov_base++; 10412792Ssam iov->iov_len--; 10512792Ssam uio->uio_resid--; 10612792Ssam uio->uio_offset++; 10712792Ssam return (0); 10812792Ssam } 10912792Ssam 11052497Storek #ifdef vax /* unused except by ct.c, other oddities XXX */ 11112792Ssam /* 11212792Ssam * Get next character written in by user from uio. 11312792Ssam */ 11412792Ssam uwritec(uio) 11512792Ssam struct uio *uio; 11612792Ssam { 11712792Ssam register struct iovec *iov; 11812792Ssam register int c; 11912792Ssam 12027235Skarels if (uio->uio_resid <= 0) 12127235Skarels return (-1); 12212792Ssam again: 12327235Skarels if (uio->uio_iovcnt <= 0) 12412792Ssam panic("uwritec"); 12512792Ssam iov = uio->uio_iov; 12612792Ssam if (iov->iov_len == 0) { 12712792Ssam uio->uio_iov++; 12827235Skarels if (--uio->uio_iovcnt == 0) 12927235Skarels return (-1); 13012792Ssam goto again; 13112792Ssam } 13212792Ssam switch (uio->uio_segflg) { 13312792Ssam 13416704Smckusick case UIO_USERSPACE: 13512792Ssam c = fubyte(iov->iov_base); 13612792Ssam break; 13712792Ssam 13816704Smckusick case UIO_SYSSPACE: 13947540Skarels c = *(u_char *) iov->iov_base; 14012792Ssam break; 14112792Ssam 14216704Smckusick case UIO_USERISPACE: 14312792Ssam c = fuibyte(iov->iov_base); 14412792Ssam break; 14512792Ssam } 14612792Ssam if (c < 0) 14712792Ssam return (-1); 14812792Ssam iov->iov_base++; 14912792Ssam iov->iov_len--; 15012792Ssam uio->uio_resid--; 15112792Ssam uio->uio_offset++; 15247540Skarels return (c); 15312792Ssam } 15452497Storek #endif /* vax */ 15555404Smckusick 15655404Smckusick /* 15755404Smckusick * General routine to allocate a hash table. 15855404Smckusick */ 15955404Smckusick void * 16055404Smckusick hashinit(elements, type, hashmask) 16155404Smckusick int elements, type; 16255404Smckusick u_long *hashmask; 16355404Smckusick { 16455404Smckusick long hashsize; 16555404Smckusick void *hashtbl; 16655404Smckusick 16755404Smckusick if (elements <= 0) 16855404Smckusick panic("hashinit: bad cnt"); 16955404Smckusick for (hashsize = 1; hashsize <= elements; hashsize <<= 1) 17055404Smckusick continue; 17155404Smckusick hashsize >>= 1; 17255404Smckusick hashtbl = malloc((u_long)hashsize * sizeof(void *), type, M_WAITOK); 17355404Smckusick bzero(hashtbl, hashsize * sizeof(void *)); 17455404Smckusick *hashmask = hashsize - 1; 17555404Smckusick return (hashtbl); 17655404Smckusick } 177