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.7 (Berkeley) 04/15/91 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 24 #ifdef DIAGNOSTIC 25 if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) 26 panic("uiomove: mode"); 27 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc) 28 panic("uiomove proc"); 29 #endif 30 while (n > 0 && uio->uio_resid) { 31 iov = uio->uio_iov; 32 cnt = iov->iov_len; 33 if (cnt == 0) { 34 uio->uio_iov++; 35 uio->uio_iovcnt--; 36 continue; 37 } 38 if (cnt > n) 39 cnt = n; 40 switch (uio->uio_segflg) { 41 42 case UIO_USERSPACE: 43 case UIO_USERISPACE: 44 if (uio->uio_rw == UIO_READ) 45 error = copyout(cp, iov->iov_base, cnt); 46 else 47 error = copyin(iov->iov_base, cp, cnt); 48 if (error) 49 return (error); 50 break; 51 52 case UIO_SYSSPACE: 53 if (uio->uio_rw == UIO_READ) 54 bcopy((caddr_t)cp, iov->iov_base, cnt); 55 else 56 bcopy(iov->iov_base, (caddr_t)cp, cnt); 57 break; 58 } 59 iov->iov_base += cnt; 60 iov->iov_len -= cnt; 61 uio->uio_resid -= cnt; 62 uio->uio_offset += cnt; 63 cp += cnt; 64 n -= cnt; 65 } 66 return (error); 67 } 68 69 /* 70 * Give next character to user as result of read. 71 */ 72 ureadc(c, uio) 73 register int c; 74 register struct uio *uio; 75 { 76 register struct iovec *iov; 77 78 again: 79 if (uio->uio_iovcnt == 0) 80 panic("ureadc"); 81 iov = uio->uio_iov; 82 if (iov->iov_len <= 0 || uio->uio_resid <= 0) { 83 uio->uio_iovcnt--; 84 uio->uio_iov++; 85 goto again; 86 } 87 switch (uio->uio_segflg) { 88 89 case UIO_USERSPACE: 90 if (subyte(iov->iov_base, c) < 0) 91 return (EFAULT); 92 break; 93 94 case UIO_SYSSPACE: 95 *iov->iov_base = c; 96 break; 97 98 case UIO_USERISPACE: 99 if (suibyte(iov->iov_base, c) < 0) 100 return (EFAULT); 101 break; 102 } 103 iov->iov_base++; 104 iov->iov_len--; 105 uio->uio_resid--; 106 uio->uio_offset++; 107 return (0); 108 } 109 110 strcat(src, append) 111 register char *src, *append; 112 { 113 114 for (; *src; ++src) 115 ; 116 while (*src++ = *append++) 117 ; 118 } 119 120 strcpy(to, from) 121 register char *to, *from; 122 { 123 124 for (; *from = *to; ++from, ++to) 125 ; 126 } 127 128 strncpy(to, from, cnt) 129 register char *to, *from; 130 register int cnt; 131 { 132 133 for (; cnt && (*to = *from); --cnt, ++from, ++to) 134 ; 135 *to = '\0'; 136 } 137 138 #ifndef lint /* unused except by ct.c, other oddities XXX */ 139 /* 140 * Get next character written in by user from uio. 141 */ 142 uwritec(uio) 143 struct uio *uio; 144 { 145 register struct iovec *iov; 146 register int c; 147 148 if (uio->uio_resid <= 0) 149 return (-1); 150 again: 151 if (uio->uio_iovcnt <= 0) 152 panic("uwritec"); 153 iov = uio->uio_iov; 154 if (iov->iov_len == 0) { 155 uio->uio_iov++; 156 if (--uio->uio_iovcnt == 0) 157 return (-1); 158 goto again; 159 } 160 switch (uio->uio_segflg) { 161 162 case UIO_USERSPACE: 163 c = fubyte(iov->iov_base); 164 break; 165 166 case UIO_SYSSPACE: 167 c = *(u_char *) iov->iov_base; 168 break; 169 170 case UIO_USERISPACE: 171 c = fuibyte(iov->iov_base); 172 break; 173 } 174 if (c < 0) 175 return (-1); 176 iov->iov_base++; 177 iov->iov_len--; 178 uio->uio_resid--; 179 uio->uio_offset++; 180 return (c); 181 } 182 #endif /* notdef */ 183