|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
23: /*
24: * Copyright (c) 1982, 1986, 1991, 1993
25: * The Regents of the University of California. All rights reserved.
26: * (c) UNIX System Laboratories, Inc.
27: * All or some portions of this file are derived from material licensed
28: * to the University of California by American Telephone and Telegraph
29: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
30: * the permission of UNIX System Laboratories, Inc.
31: *
32: * Redistribution and use in source and binary forms, with or without
33: * modification, are permitted provided that the following conditions
34: * are met:
35: * 1. Redistributions of source code must retain the above copyright
36: * notice, this list of conditions and the following disclaimer.
37: * 2. Redistributions in binary form must reproduce the above copyright
38: * notice, this list of conditions and the following disclaimer in the
39: * documentation and/or other materials provided with the distribution.
40: * 3. All advertising materials mentioning features or use of this software
41: * must display the following acknowledgement:
42: * This product includes software developed by the University of
43: * California, Berkeley and its contributors.
44: * 4. Neither the name of the University nor the names of its contributors
45: * may be used to endorse or promote products derived from this software
46: * without specific prior written permission.
47: *
48: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58: * SUCH DAMAGE.
59: *
60: * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
61: */
62:
63: #include <sys/param.h>
64: #include <sys/systm.h>
65: #include <sys/proc.h>
66: #include <sys/malloc.h>
67: #include <sys/queue.h>
68:
69: #include <kdebug.h>
70: #if KDEBUG
71: #include <sys/kdebug.h>
72: #define DBG_UIO_COPYOUT 16
73: #define DBG_UIO_COPYIN 17
74: #endif /* KDEBUG */
75:
76: int
77: uiomove(cp, n, uio)
78: register caddr_t cp;
79: register int n;
80: register struct uio *uio;
81: {
82: register struct iovec *iov;
83: u_int cnt;
84: int error = 0;
85:
86: #if DIAGNOSTIC
87: if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
88: panic("uiomove: mode");
89: if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != current_proc())
90: panic("uiomove proc");
91: #endif
92:
93: while (n > 0 && uio->uio_resid) {
94: iov = uio->uio_iov;
95: cnt = iov->iov_len;
96: if (cnt == 0) {
97: uio->uio_iov++;
98: uio->uio_iovcnt--;
99: continue;
100: }
101: if (cnt > n)
102: cnt = n;
103: switch (uio->uio_segflg) {
104:
105: case UIO_USERSPACE:
106: case UIO_USERISPACE:
107: if (uio->uio_rw == UIO_READ)
108: {
109: #if KDEBUG
110: KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_START,
111: cp, iov->iov_base, cnt, 0,0);
112: #endif /* KDEBUG */
113:
114: error = copyout(cp, iov->iov_base, cnt);
115:
116: #if KDEBUG
117: KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_END,
118: cp, iov->iov_base, cnt, 0,0);
119: #endif /* KDEBUG */
120: }
121: else
122: {
123: #if KDEBUG
124: KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_START,
125: iov->iov_base, cp, cnt, 0,0);
126: #endif /* KDEBUG */
127:
128: error = copyin(iov->iov_base, cp, cnt);
129: #if KDEBUG
130:
131: KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_END,
132: iov->iov_base, cp, cnt, 0,0);
133: #endif /* KDEBUG */
134: }
135: if (error)
136: return (error);
137: break;
138:
139: case UIO_SYSSPACE:
140: if (uio->uio_rw == UIO_READ)
141: error = copywithin((caddr_t)cp, iov->iov_base,
142: cnt);
143: else
144: error = copywithin(iov->iov_base, (caddr_t)cp,
145: cnt);
146: break;
147: }
148: iov->iov_base += cnt;
149: iov->iov_len -= cnt;
150: uio->uio_resid -= cnt;
151: uio->uio_offset += cnt;
152: cp += cnt;
153: n -= cnt;
154: }
155: return (error);
156: }
157:
158: /*
159: * Give next character to user as result of read.
160: */
161: int
162: ureadc(c, uio)
163: register int c;
164: register struct uio *uio;
165: {
166: register struct iovec *iov;
167:
168: if (uio->uio_resid <= 0)
169: panic("ureadc: non-positive resid");
170: again:
171: if (uio->uio_iovcnt == 0)
172: panic("ureadc: non-positive iovcnt");
173: iov = uio->uio_iov;
174: if (iov->iov_len <= 0) {
175: uio->uio_iovcnt--;
176: uio->uio_iov++;
177: goto again;
178: }
179: switch (uio->uio_segflg) {
180:
181: case UIO_USERSPACE:
182: if (subyte(iov->iov_base, c) < 0)
183: return (EFAULT);
184: break;
185:
186: case UIO_SYSSPACE:
187: *iov->iov_base = c;
188: break;
189:
190: case UIO_USERISPACE:
191: if (suibyte(iov->iov_base, c) < 0)
192: return (EFAULT);
193: break;
194: }
195: iov->iov_base++;
196: iov->iov_len--;
197: uio->uio_resid--;
198: uio->uio_offset++;
199: return (0);
200: }
201:
202: #if defined(vax) || defined(ppc)
203: /* unused except by ct.c, other oddities XXX */
204: /*
205: * Get next character written in by user from uio.
206: */
207: uwritec(uio)
208: struct uio *uio;
209: {
210: register struct iovec *iov;
211: register int c;
212:
213: if (uio->uio_resid <= 0)
214: return (-1);
215: again:
216: if (uio->uio_iovcnt <= 0)
217: panic("uwritec: non-positive iovcnt");
218: iov = uio->uio_iov;
219: if (iov->iov_len == 0) {
220: uio->uio_iov++;
221: if (--uio->uio_iovcnt == 0)
222: return (-1);
223: goto again;
224: }
225: switch (uio->uio_segflg) {
226:
227: case UIO_USERSPACE:
228: c = fubyte(iov->iov_base);
229: break;
230:
231: case UIO_SYSSPACE:
232: c = *iov->iov_base & 0377;
233: break;
234:
235: case UIO_USERISPACE:
236: c = fuibyte(iov->iov_base);
237: break;
238:
239: default:
240: c = 0; /* avoid uninitialized variable warning */
241: panic("uwritec: bogus uio_segflg");
242: break;
243: }
244: if (c < 0)
245: return (-1);
246: iov->iov_base++;
247: iov->iov_len--;
248: uio->uio_resid--;
249: uio->uio_offset++;
250: return (c);
251: }
252: #endif /* vax || ppc */
253:
254: /*
255: * General routine to allocate a hash table.
256: */
257: void *
258: hashinit(elements, type, hashmask)
259: int elements, type;
260: u_long *hashmask;
261: {
262: long hashsize;
263: LIST_HEAD(generic, generic) *hashtbl;
264: int i;
265:
266: if (elements <= 0)
267: panic("hashinit: bad cnt");
268: for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
269: continue;
270: hashsize >>= 1;
271: MALLOC(hashtbl, struct generic *,
272: (u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
273: bzero(hashtbl, (u_long)hashsize * sizeof(*hashtbl));
274: for (i = 0; i < hashsize; i++)
275: LIST_INIT(&hashtbl[i]);
276: *hashmask = hashsize - 1;
277: return (hashtbl);
278: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.