1 /* 2 * Copyright (c) 1982 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 6.5 (Berkeley) 04/21/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 } 148