1: /* 2: * Copyright (c) 1982, 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)kern_subr.c 7.1 (Berkeley) 6/5/86 7: */ 8: 9: #include "param.h" 10: #include "systm.h" 11: #include "dir.h" 12: #include "user.h" 13: #include "uio.h" 14: 15: uiomove(cp, n, rw, uio) 16: register caddr_t cp; 17: register int n; 18: enum uio_rw rw; 19: register struct uio *uio; 20: { 21: register struct iovec *iov; 22: u_int cnt; 23: int error = 0; 24: 25: while (n > 0 && uio->uio_resid) { 26: iov = uio->uio_iov; 27: cnt = iov->iov_len; 28: if (cnt == 0) { 29: uio->uio_iov++; 30: uio->uio_iovcnt--; 31: continue; 32: } 33: if (cnt > n) 34: cnt = n; 35: switch (uio->uio_segflg) { 36: 37: case UIO_USERSPACE: 38: case UIO_USERISPACE: 39: if (rw == UIO_READ) 40: error = copyout(cp, iov->iov_base, cnt); 41: else 42: error = copyin(iov->iov_base, cp, cnt); 43: if (error) 44: return (error); 45: break; 46: 47: case UIO_SYSSPACE: 48: if (rw == UIO_READ) 49: bcopy((caddr_t)cp, iov->iov_base, cnt); 50: else 51: bcopy(iov->iov_base, (caddr_t)cp, cnt); 52: break; 53: } 54: iov->iov_base += cnt; 55: iov->iov_len -= cnt; 56: uio->uio_resid -= cnt; 57: uio->uio_offset += cnt; 58: cp += cnt; 59: n -= cnt; 60: } 61: return (error); 62: } 63: 64: /* 65: * Give next character to user as result of read. 66: */ 67: ureadc(c, uio) 68: register int c; 69: register struct uio *uio; 70: { 71: register struct iovec *iov; 72: 73: again: 74: if (uio->uio_iovcnt == 0) 75: panic("ureadc"); 76: iov = uio->uio_iov; 77: if (iov->iov_len <= 0 || uio->uio_resid <= 0) { 78: uio->uio_iovcnt--; 79: uio->uio_iov++; 80: goto again; 81: } 82: switch (uio->uio_segflg) { 83: 84: case UIO_USERSPACE: 85: if (subyte(iov->iov_base, c) < 0) 86: return (EFAULT); 87: break; 88: 89: case UIO_SYSSPACE: 90: *iov->iov_base = c; 91: break; 92: 93: case UIO_USERISPACE: 94: if (suibyte(iov->iov_base, c) < 0) 95: return (EFAULT); 96: break; 97: } 98: iov->iov_base++; 99: iov->iov_len--; 100: uio->uio_resid--; 101: uio->uio_offset++; 102: return (0); 103: } 104: 105: /* 106: * Get next character written in by user from uio. 107: */ 108: uwritec(uio) 109: struct uio *uio; 110: { 111: register struct iovec *iov; 112: register int c; 113: 114: if (uio->uio_resid <= 0) 115: return (-1); 116: again: 117: if (uio->uio_iovcnt <= 0) 118: panic("uwritec"); 119: iov = uio->uio_iov; 120: if (iov->iov_len == 0) { 121: uio->uio_iov++; 122: if (--uio->uio_iovcnt == 0) 123: return (-1); 124: goto again; 125: } 126: switch (uio->uio_segflg) { 127: 128: case UIO_USERSPACE: 129: c = fubyte(iov->iov_base); 130: break; 131: 132: case UIO_SYSSPACE: 133: c = *iov->iov_base & 0377; 134: break; 135: 136: case UIO_USERISPACE: 137: c = fuibyte(iov->iov_base); 138: break; 139: } 140: if (c < 0) 141: return (-1); 142: iov->iov_base++; 143: iov->iov_len--; 144: uio->uio_resid--; 145: uio->uio_offset++; 146: return (c & 0377); 147: }