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