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