subr_hash.c revision 1542
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
47uiomove(cp, n, uio)
48	register caddr_t cp;
49	register int n;
50	register struct uio *uio;
51{
52	register struct iovec *iov;
53	u_int cnt;
54	int error = 0;
55
56#ifdef DIAGNOSTIC
57	if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
58		panic("uiomove: mode");
59	if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
60		panic("uiomove proc");
61#endif
62	while (n > 0 && uio->uio_resid) {
63		iov = uio->uio_iov;
64		cnt = iov->iov_len;
65		if (cnt == 0) {
66			uio->uio_iov++;
67			uio->uio_iovcnt--;
68			continue;
69		}
70		if (cnt > n)
71			cnt = n;
72		switch (uio->uio_segflg) {
73
74		case UIO_USERSPACE:
75		case UIO_USERISPACE:
76			if (uio->uio_rw == UIO_READ)
77				error = copyout(cp, iov->iov_base, cnt);
78			else
79				error = copyin(iov->iov_base, cp, cnt);
80			if (error)
81				return (error);
82			break;
83
84		case UIO_SYSSPACE:
85			if (uio->uio_rw == UIO_READ)
86				bcopy((caddr_t)cp, iov->iov_base, cnt);
87			else
88				bcopy(iov->iov_base, (caddr_t)cp, cnt);
89			break;
90		}
91		iov->iov_base += cnt;
92		iov->iov_len -= cnt;
93		uio->uio_resid -= cnt;
94		uio->uio_offset += cnt;
95		cp += cnt;
96		n -= cnt;
97	}
98	return (error);
99}
100
101/*
102 * Give next character to user as result of read.
103 */
104ureadc(c, uio)
105	register int c;
106	register struct uio *uio;
107{
108	register struct iovec *iov;
109
110again:
111	if (uio->uio_iovcnt == 0 || uio->uio_resid == 0)
112		panic("ureadc");
113	iov = uio->uio_iov;
114	if (iov->iov_len == 0) {
115		uio->uio_iovcnt--;
116		uio->uio_iov++;
117		goto again;
118	}
119	switch (uio->uio_segflg) {
120
121	case UIO_USERSPACE:
122		if (subyte(iov->iov_base, c) < 0)
123			return (EFAULT);
124		break;
125
126	case UIO_SYSSPACE:
127		*iov->iov_base = c;
128		break;
129
130	case UIO_USERISPACE:
131		if (suibyte(iov->iov_base, c) < 0)
132			return (EFAULT);
133		break;
134	}
135	iov->iov_base++;
136	iov->iov_len--;
137	uio->uio_resid--;
138	uio->uio_offset++;
139	return (0);
140}
141
142#ifdef vax	/* unused except by ct.c, other oddities XXX */
143/*
144 * Get next character written in by user from uio.
145 */
146uwritec(uio)
147	struct uio *uio;
148{
149	register struct iovec *iov;
150	register int c;
151
152	if (uio->uio_resid <= 0)
153		return (-1);
154again:
155	if (uio->uio_iovcnt <= 0)
156		panic("uwritec");
157	iov = uio->uio_iov;
158	if (iov->iov_len == 0) {
159		uio->uio_iov++;
160		if (--uio->uio_iovcnt == 0)
161			return (-1);
162		goto again;
163	}
164	switch (uio->uio_segflg) {
165
166	case UIO_USERSPACE:
167		c = fubyte(iov->iov_base);
168		break;
169
170	case UIO_SYSSPACE:
171		c = *(u_char *) iov->iov_base;
172		break;
173
174	case UIO_USERISPACE:
175		c = fuibyte(iov->iov_base);
176		break;
177	}
178	if (c < 0)
179		return (-1);
180	iov->iov_base++;
181	iov->iov_len--;
182	uio->uio_resid--;
183	uio->uio_offset++;
184	return (c);
185}
186#endif /* vax */
187
188/*
189 * General routine to allocate a hash table.
190 */
191void *
192hashinit(elements, type, hashmask)
193	int elements, type;
194	u_long *hashmask;
195{
196	long hashsize;
197	LIST_HEAD(generic, generic) *hashtbl;
198	int i;
199
200	if (elements <= 0)
201		panic("hashinit: bad cnt");
202	for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
203		continue;
204	hashsize >>= 1;
205	hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
206	for (i = 0; i < hashsize; i++)
207		LIST_INIT(&hashtbl[i]);
208	*hashmask = hashsize - 1;
209	return (hashtbl);
210}
211