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