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.8 (Berkeley) 02/14/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 strcat(src, append) 110 register char *src, *append; 111 { 112 113 for (; *src; ++src) 114 continue; 115 while (*src++ = *append++) 116 continue; 117 } 118 119 strcpy(to, from) 120 register char *to, *from; 121 { 122 123 for (; *to = *from; ++from, ++to) 124 continue; 125 } 126 127 strncpy(to, from, cnt) 128 register char *to, *from; 129 register int cnt; 130 { 131 132 for (; cnt && (*to = *from); --cnt, ++from, ++to) 133 continue; 134 *to = '\0'; 135 } 136 137 #ifdef vax /* unused except by ct.c, other oddities XXX */ 138 /* 139 * Get next character written in by user from uio. 140 */ 141 uwritec(uio) 142 struct uio *uio; 143 { 144 register struct iovec *iov; 145 register int c; 146 147 if (uio->uio_resid <= 0) 148 return (-1); 149 again: 150 if (uio->uio_iovcnt <= 0) 151 panic("uwritec"); 152 iov = uio->uio_iov; 153 if (iov->iov_len == 0) { 154 uio->uio_iov++; 155 if (--uio->uio_iovcnt == 0) 156 return (-1); 157 goto again; 158 } 159 switch (uio->uio_segflg) { 160 161 case UIO_USERSPACE: 162 c = fubyte(iov->iov_base); 163 break; 164 165 case UIO_SYSSPACE: 166 c = *(u_char *) iov->iov_base; 167 break; 168 169 case UIO_USERISPACE: 170 c = fuibyte(iov->iov_base); 171 break; 172 } 173 if (c < 0) 174 return (-1); 175 iov->iov_base++; 176 iov->iov_len--; 177 uio->uio_resid--; 178 uio->uio_offset++; 179 return (c); 180 } 181 #endif /* vax */ 182