123375Smckusick /* 229095Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323375Smckusick * All rights reserved. The Berkeley software License Agreement 423375Smckusick * specifies the terms and conditions for redistribution. 523375Smckusick * 6*37728Smckusick * @(#)kern_subr.c 7.2 (Berkeley) 05/09/89 723375Smckusick */ 812792Ssam 917093Sbloom #include "param.h" 1017093Sbloom #include "systm.h" 1117093Sbloom #include "user.h" 1212792Ssam 13*37728Smckusick uiomove(cp, n, uio) 1412792Ssam register caddr_t cp; 1512792Ssam register int n; 1612792Ssam register struct uio *uio; 1712792Ssam { 1812792Ssam register struct iovec *iov; 1912792Ssam u_int cnt; 2012792Ssam int error = 0; 2112792Ssam 22*37728Smckusick if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) 23*37728Smckusick panic("uiomove: mode"); 2412792Ssam while (n > 0 && uio->uio_resid) { 2512792Ssam iov = uio->uio_iov; 2612792Ssam cnt = iov->iov_len; 2712792Ssam if (cnt == 0) { 2812792Ssam uio->uio_iov++; 2912792Ssam uio->uio_iovcnt--; 3012792Ssam continue; 3112792Ssam } 3212792Ssam if (cnt > n) 3312792Ssam cnt = n; 3412792Ssam switch (uio->uio_segflg) { 3512792Ssam 3616704Smckusick case UIO_USERSPACE: 3716704Smckusick case UIO_USERISPACE: 38*37728Smckusick if (uio->uio_rw == UIO_READ) 3912792Ssam error = copyout(cp, iov->iov_base, cnt); 4012792Ssam else 4112792Ssam error = copyin(iov->iov_base, cp, cnt); 4212792Ssam if (error) 4312792Ssam return (error); 4412792Ssam break; 4512792Ssam 4616704Smckusick case UIO_SYSSPACE: 47*37728Smckusick if (uio->uio_rw == UIO_READ) 4812792Ssam bcopy((caddr_t)cp, iov->iov_base, cnt); 4912792Ssam else 5012792Ssam bcopy(iov->iov_base, (caddr_t)cp, cnt); 5112792Ssam break; 5212792Ssam } 5312792Ssam iov->iov_base += cnt; 5412792Ssam iov->iov_len -= cnt; 5512792Ssam uio->uio_resid -= cnt; 5612792Ssam uio->uio_offset += cnt; 5712792Ssam cp += cnt; 5812792Ssam n -= cnt; 5912792Ssam } 6012792Ssam return (error); 6112792Ssam } 6212792Ssam 6312792Ssam /* 6412792Ssam * Give next character to user as result of read. 6512792Ssam */ 6612792Ssam ureadc(c, uio) 6712792Ssam register int c; 6812792Ssam register struct uio *uio; 6912792Ssam { 7012792Ssam register struct iovec *iov; 7112792Ssam 7212792Ssam again: 7312792Ssam if (uio->uio_iovcnt == 0) 7412792Ssam panic("ureadc"); 7512792Ssam iov = uio->uio_iov; 7612792Ssam if (iov->iov_len <= 0 || uio->uio_resid <= 0) { 7712792Ssam uio->uio_iovcnt--; 7812792Ssam uio->uio_iov++; 7912792Ssam goto again; 8012792Ssam } 8112792Ssam switch (uio->uio_segflg) { 8212792Ssam 8316704Smckusick case UIO_USERSPACE: 8412792Ssam if (subyte(iov->iov_base, c) < 0) 8512792Ssam return (EFAULT); 8612792Ssam break; 8712792Ssam 8816704Smckusick case UIO_SYSSPACE: 8912792Ssam *iov->iov_base = c; 9012792Ssam break; 9112792Ssam 9216704Smckusick case UIO_USERISPACE: 9312792Ssam if (suibyte(iov->iov_base, c) < 0) 9412792Ssam return (EFAULT); 9512792Ssam break; 9612792Ssam } 9712792Ssam iov->iov_base++; 9812792Ssam iov->iov_len--; 9912792Ssam uio->uio_resid--; 10012792Ssam uio->uio_offset++; 10112792Ssam return (0); 10212792Ssam } 10312792Ssam 104*37728Smckusick #ifdef unused 10512792Ssam /* 10612792Ssam * Get next character written in by user from uio. 10712792Ssam */ 10812792Ssam uwritec(uio) 10912792Ssam struct uio *uio; 11012792Ssam { 11112792Ssam register struct iovec *iov; 11212792Ssam register int c; 11312792Ssam 11427235Skarels if (uio->uio_resid <= 0) 11527235Skarels return (-1); 11612792Ssam again: 11727235Skarels if (uio->uio_iovcnt <= 0) 11812792Ssam panic("uwritec"); 11912792Ssam iov = uio->uio_iov; 12012792Ssam if (iov->iov_len == 0) { 12112792Ssam uio->uio_iov++; 12227235Skarels if (--uio->uio_iovcnt == 0) 12327235Skarels return (-1); 12412792Ssam goto again; 12512792Ssam } 12612792Ssam switch (uio->uio_segflg) { 12712792Ssam 12816704Smckusick case UIO_USERSPACE: 12912792Ssam c = fubyte(iov->iov_base); 13012792Ssam break; 13112792Ssam 13216704Smckusick case UIO_SYSSPACE: 13312792Ssam c = *iov->iov_base & 0377; 13412792Ssam break; 13512792Ssam 13616704Smckusick case UIO_USERISPACE: 13712792Ssam c = fuibyte(iov->iov_base); 13812792Ssam break; 13912792Ssam } 14012792Ssam if (c < 0) 14112792Ssam return (-1); 14212792Ssam iov->iov_base++; 14312792Ssam iov->iov_len--; 14412792Ssam uio->uio_resid--; 14512792Ssam uio->uio_offset++; 14612792Ssam return (c & 0377); 14712792Ssam } 148*37728Smckusick #endif /* unused */ 149