xref: /original-bsd/sys/kern/kern_subr.c (revision e78e7ec3)
1 /*	kern_subr.c	6.3	84/08/29	*/
2 
3 #include "param.h"
4 #include "systm.h"
5 #include "dir.h"
6 #include "user.h"
7 #include "uio.h"
8 
9 uiomove(cp, n, rw, uio)
10 	register caddr_t cp;
11 	register int n;
12 	enum uio_rw rw;
13 	register struct uio *uio;
14 {
15 	register struct iovec *iov;
16 	u_int cnt;
17 	int error = 0;
18 
19 	while (n > 0 && uio->uio_resid) {
20 		iov = uio->uio_iov;
21 		cnt = iov->iov_len;
22 		if (cnt == 0) {
23 			uio->uio_iov++;
24 			uio->uio_iovcnt--;
25 			continue;
26 		}
27 		if (cnt > n)
28 			cnt = n;
29 		switch (uio->uio_segflg) {
30 
31 		case UIO_USERSPACE:
32 		case UIO_USERISPACE:
33 			if (rw == UIO_READ)
34 				error = copyout(cp, iov->iov_base, cnt);
35 			else
36 				error = copyin(iov->iov_base, cp, cnt);
37 			if (error)
38 				return (error);
39 			break;
40 
41 		case UIO_SYSSPACE:
42 			if (rw == UIO_READ)
43 				bcopy((caddr_t)cp, iov->iov_base, cnt);
44 			else
45 				bcopy(iov->iov_base, (caddr_t)cp, cnt);
46 			break;
47 		}
48 		iov->iov_base += cnt;
49 		iov->iov_len -= cnt;
50 		uio->uio_resid -= cnt;
51 		uio->uio_offset += cnt;
52 		cp += cnt;
53 		n -= cnt;
54 	}
55 	return (error);
56 }
57 
58 /*
59  * Give next character to user as result of read.
60  */
61 ureadc(c, uio)
62 	register int c;
63 	register struct uio *uio;
64 {
65 	register struct iovec *iov;
66 
67 again:
68 	if (uio->uio_iovcnt == 0)
69 		panic("ureadc");
70 	iov = uio->uio_iov;
71 	if (iov->iov_len <= 0 || uio->uio_resid <= 0) {
72 		uio->uio_iovcnt--;
73 		uio->uio_iov++;
74 		goto again;
75 	}
76 	switch (uio->uio_segflg) {
77 
78 	case UIO_USERSPACE:
79 		if (subyte(iov->iov_base, c) < 0)
80 			return (EFAULT);
81 		break;
82 
83 	case UIO_SYSSPACE:
84 		*iov->iov_base = c;
85 		break;
86 
87 	case UIO_USERISPACE:
88 		if (suibyte(iov->iov_base, c) < 0)
89 			return (EFAULT);
90 		break;
91 	}
92 	iov->iov_base++;
93 	iov->iov_len--;
94 	uio->uio_resid--;
95 	uio->uio_offset++;
96 	return (0);
97 }
98 
99 #ifdef notdef
100 /*
101  * Get next character written in by user from uio.
102  */
103 uwritec(uio)
104 	struct uio *uio;
105 {
106 	register struct iovec *iov;
107 	register int c;
108 
109 again:
110 	if (uio->uio_iovcnt <= 0 || uio->uio_resid <= 0)
111 		panic("uwritec");
112 	iov = uio->uio_iov;
113 	if (iov->iov_len == 0) {
114 		uio->uio_iovcnt--;
115 		uio->uio_iov++;
116 		goto again;
117 	}
118 	switch (uio->uio_segflg) {
119 
120 	case UIO_USERSPACE:
121 		c = fubyte(iov->iov_base);
122 		break;
123 
124 	case UIO_SYSSPACE:
125 		c = *iov->iov_base & 0377;
126 		break;
127 
128 	case UIO_USERISPACE:
129 		c = fuibyte(iov->iov_base);
130 		break;
131 	}
132 	if (c < 0)
133 		return (-1);
134 	iov->iov_base++;
135 	iov->iov_len--;
136 	uio->uio_resid--;
137 	uio->uio_offset++;
138 	return (c & 0377);
139 }
140 #endif
141