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.2 (Berkeley) 05/09/89 7 */ 8 9 #include "param.h" 10 #include "systm.h" 11 #include "user.h" 12 13 uiomove(cp, n, uio) 14 register caddr_t cp; 15 register int n; 16 register struct uio *uio; 17 { 18 register struct iovec *iov; 19 u_int cnt; 20 int error = 0; 21 22 if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) 23 panic("uiomove: mode"); 24 while (n > 0 && uio->uio_resid) { 25 iov = uio->uio_iov; 26 cnt = iov->iov_len; 27 if (cnt == 0) { 28 uio->uio_iov++; 29 uio->uio_iovcnt--; 30 continue; 31 } 32 if (cnt > n) 33 cnt = n; 34 switch (uio->uio_segflg) { 35 36 case UIO_USERSPACE: 37 case UIO_USERISPACE: 38 if (uio->uio_rw == UIO_READ) 39 error = copyout(cp, iov->iov_base, cnt); 40 else 41 error = copyin(iov->iov_base, cp, cnt); 42 if (error) 43 return (error); 44 break; 45 46 case UIO_SYSSPACE: 47 if (uio->uio_rw == UIO_READ) 48 bcopy((caddr_t)cp, iov->iov_base, cnt); 49 else 50 bcopy(iov->iov_base, (caddr_t)cp, cnt); 51 break; 52 } 53 iov->iov_base += cnt; 54 iov->iov_len -= cnt; 55 uio->uio_resid -= cnt; 56 uio->uio_offset += cnt; 57 cp += cnt; 58 n -= cnt; 59 } 60 return (error); 61 } 62 63 /* 64 * Give next character to user as result of read. 65 */ 66 ureadc(c, uio) 67 register int c; 68 register struct uio *uio; 69 { 70 register struct iovec *iov; 71 72 again: 73 if (uio->uio_iovcnt == 0) 74 panic("ureadc"); 75 iov = uio->uio_iov; 76 if (iov->iov_len <= 0 || uio->uio_resid <= 0) { 77 uio->uio_iovcnt--; 78 uio->uio_iov++; 79 goto again; 80 } 81 switch (uio->uio_segflg) { 82 83 case UIO_USERSPACE: 84 if (subyte(iov->iov_base, c) < 0) 85 return (EFAULT); 86 break; 87 88 case UIO_SYSSPACE: 89 *iov->iov_base = c; 90 break; 91 92 case UIO_USERISPACE: 93 if (suibyte(iov->iov_base, c) < 0) 94 return (EFAULT); 95 break; 96 } 97 iov->iov_base++; 98 iov->iov_len--; 99 uio->uio_resid--; 100 uio->uio_offset++; 101 return (0); 102 } 103 104 #ifdef unused 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 #endif /* unused */ 149