subr_hash.c revision 1549
1/*
2 * Copyright (c) 1982, 1986, 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	@(#)kern_subr.c	8.3 (Berkeley) 1/21/94
39 */
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/proc.h>
44#include <sys/malloc.h>
45#include <sys/queue.h>
46
47int
48uiomove(cp, n, uio)
49	register caddr_t cp;
50	register int n;
51	register struct uio *uio;
52{
53	register struct iovec *iov;
54	u_int cnt;
55	int error = 0;
56
57#ifdef DIAGNOSTIC
58	if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
59		panic("uiomove: mode");
60	if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
61		panic("uiomove proc");
62#endif
63	while (n > 0 && uio->uio_resid) {
64		iov = uio->uio_iov;
65		cnt = iov->iov_len;
66		if (cnt == 0) {
67			uio->uio_iov++;
68			uio->uio_iovcnt--;
69			continue;
70		}
71		if (cnt > n)
72			cnt = n;
73		switch (uio->uio_segflg) {
74
75		case UIO_USERSPACE:
76		case UIO_USERISPACE:
77			if (uio->uio_rw == UIO_READ)
78				error = copyout(cp, iov->iov_base, cnt);
79			else
80				error = copyin(iov->iov_base, cp, cnt);
81			if (error)
82				return (error);
83			break;
84
85		case UIO_SYSSPACE:
86			if (uio->uio_rw == UIO_READ)
87				bcopy((caddr_t)cp, iov->iov_base, cnt);
88			else
89				bcopy(iov->iov_base, (caddr_t)cp, cnt);
90			break;
91		}
92		iov->iov_base += cnt;
93		iov->iov_len -= cnt;
94		uio->uio_resid -= cnt;
95		uio->uio_offset += cnt;
96		cp += cnt;
97		n -= cnt;
98	}
99	return (error);
100}
101
102/*
103 * Give next character to user as result of read.
104 */
105int
106ureadc(c, uio)
107	register int c;
108	register struct uio *uio;
109{
110	register struct iovec *iov;
111
112again:
113	if (uio->uio_iovcnt == 0 || uio->uio_resid == 0)
114		panic("ureadc");
115	iov = uio->uio_iov;
116	if (iov->iov_len == 0) {
117		uio->uio_iovcnt--;
118		uio->uio_iov++;
119		goto again;
120	}
121	switch (uio->uio_segflg) {
122
123	case UIO_USERSPACE:
124		if (subyte(iov->iov_base, c) < 0)
125			return (EFAULT);
126		break;
127
128	case UIO_SYSSPACE:
129		*iov->iov_base = c;
130		break;
131
132	case UIO_USERISPACE:
133		if (suibyte(iov->iov_base, c) < 0)
134			return (EFAULT);
135		break;
136	}
137	iov->iov_base++;
138	iov->iov_len--;
139	uio->uio_resid--;
140	uio->uio_offset++;
141	return (0);
142}
143
144#ifdef vax	/* unused except by ct.c, other oddities XXX */
145/*
146 * Get next character written in by user from uio.
147 */
148int
149uwritec(uio)
150	struct uio *uio;
151{
152	register struct iovec *iov;
153	register int c;
154
155	if (uio->uio_resid <= 0)
156		return (-1);
157again:
158	if (uio->uio_iovcnt <= 0)
159		panic("uwritec");
160	iov = uio->uio_iov;
161	if (iov->iov_len == 0) {
162		uio->uio_iov++;
163		if (--uio->uio_iovcnt == 0)
164			return (-1);
165		goto again;
166	}
167	switch (uio->uio_segflg) {
168
169	case UIO_USERSPACE:
170		c = fubyte(iov->iov_base);
171		break;
172
173	case UIO_SYSSPACE:
174		c = *(u_char *) iov->iov_base;
175		break;
176
177	case UIO_USERISPACE:
178		c = fuibyte(iov->iov_base);
179		break;
180	}
181	if (c < 0)
182		return (-1);
183	iov->iov_base++;
184	iov->iov_len--;
185	uio->uio_resid--;
186	uio->uio_offset++;
187	return (c);
188}
189#endif /* vax */
190
191/*
192 * General routine to allocate a hash table.
193 */
194void *
195hashinit(elements, type, hashmask)
196	int elements, type;
197	u_long *hashmask;
198{
199	long hashsize;
200	LIST_HEAD(generic, generic) *hashtbl;
201	int i;
202
203	if (elements <= 0)
204		panic("hashinit: bad cnt");
205	for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
206		continue;
207	hashsize >>= 1;
208	hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
209	for (i = 0; i < hashsize; i++)
210		LIST_INIT(&hashtbl[i]);
211	*hashmask = hashsize - 1;
212	return (hashtbl);
213}
214