xref: /original-bsd/sys/kern/kern_subr.c (revision 753853ba)
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