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