subr_hash.c revision 1542
1171095Ssam/*
2171095Ssam * Copyright (c) 1982, 1986, 1991, 1993
3171095Ssam *	The Regents of the University of California.  All rights reserved.
4171095Ssam * (c) UNIX System Laboratories, Inc.
5171095Ssam * All or some portions of this file are derived from material licensed
6171095Ssam * to the University of California by American Telephone and Telegraph
7171095Ssam * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8171095Ssam * the permission of UNIX System Laboratories, Inc.
9171095Ssam *
10171095Ssam * Redistribution and use in source and binary forms, with or without
11171095Ssam * modification, are permitted provided that the following conditions
12171095Ssam * are met:
13171095Ssam * 1. Redistributions of source code must retain the above copyright
14171095Ssam *    notice, this list of conditions and the following disclaimer.
15171095Ssam * 2. Redistributions in binary form must reproduce the above copyright
16171095Ssam *    notice, this list of conditions and the following disclaimer in the
17171095Ssam *    documentation and/or other materials provided with the distribution.
18171095Ssam * 3. All advertising materials mentioning features or use of this software
19171095Ssam *    must display the following acknowledgement:
20171095Ssam *	This product includes software developed by the University of
21171095Ssam *	California, Berkeley and its contributors.
22171095Ssam * 4. Neither the name of the University nor the names of its contributors
23171095Ssam *    may be used to endorse or promote products derived from this software
24171095Ssam *    without specific prior written permission.
25171095Ssam *
26171095Ssam * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27171095Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28171095Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29171095Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30171095Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31171095Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32171095Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33171095Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34171095Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35171095Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36171095Ssam * SUCH DAMAGE.
37171095Ssam *
38171095Ssam *	@(#)kern_subr.c	8.3 (Berkeley) 1/21/94
39171095Ssam */
40171095Ssam
41171095Ssam#include <sys/param.h>
42171095Ssam#include <sys/systm.h>
43171095Ssam#include <sys/proc.h>
44171095Ssam#include <sys/malloc.h>
45171095Ssam#include <sys/queue.h>
46171095Ssam
47171095Ssamuiomove(cp, n, uio)
48171095Ssam	register caddr_t cp;
49171095Ssam	register int n;
50171095Ssam	register struct uio *uio;
51171095Ssam{
52171095Ssam	register struct iovec *iov;
53171095Ssam	u_int cnt;
54171095Ssam	int error = 0;
55171095Ssam
56171095Ssam#ifdef DIAGNOSTIC
57171095Ssam	if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
58171095Ssam		panic("uiomove: mode");
59171095Ssam	if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
60171095Ssam		panic("uiomove proc");
61171095Ssam#endif
62171095Ssam	while (n > 0 && uio->uio_resid) {
63171095Ssam		iov = uio->uio_iov;
64171095Ssam		cnt = iov->iov_len;
65171095Ssam		if (cnt == 0) {
66171095Ssam			uio->uio_iov++;
67171095Ssam			uio->uio_iovcnt--;
68171095Ssam			continue;
69171095Ssam		}
70171095Ssam		if (cnt > n)
71171095Ssam			cnt = n;
72171095Ssam		switch (uio->uio_segflg) {
73171095Ssam
74171095Ssam		case UIO_USERSPACE:
75171095Ssam		case UIO_USERISPACE:
76171095Ssam			if (uio->uio_rw == UIO_READ)
77171095Ssam				error = copyout(cp, iov->iov_base, cnt);
78171095Ssam			else
79171095Ssam				error = copyin(iov->iov_base, cp, cnt);
80171095Ssam			if (error)
81171095Ssam				return (error);
82171095Ssam			break;
83171095Ssam
84171095Ssam		case UIO_SYSSPACE:
85171095Ssam			if (uio->uio_rw == UIO_READ)
86171095Ssam				bcopy((caddr_t)cp, iov->iov_base, cnt);
87171095Ssam			else
88171095Ssam				bcopy(iov->iov_base, (caddr_t)cp, cnt);
89171095Ssam			break;
90171095Ssam		}
91171095Ssam		iov->iov_base += cnt;
92171095Ssam		iov->iov_len -= cnt;
93171095Ssam		uio->uio_resid -= cnt;
94171095Ssam		uio->uio_offset += cnt;
95171095Ssam		cp += cnt;
96171095Ssam		n -= cnt;
97171095Ssam	}
98171095Ssam	return (error);
99171095Ssam}
100171095Ssam
101171095Ssam/*
102171095Ssam * Give next character to user as result of read.
103171095Ssam */
104171095Ssamureadc(c, uio)
105171095Ssam	register int c;
106171095Ssam	register struct uio *uio;
107171095Ssam{
108171095Ssam	register struct iovec *iov;
109171095Ssam
110171095Ssamagain:
111171095Ssam	if (uio->uio_iovcnt == 0 || uio->uio_resid == 0)
112171095Ssam		panic("ureadc");
113171095Ssam	iov = uio->uio_iov;
114171095Ssam	if (iov->iov_len == 0) {
115171095Ssam		uio->uio_iovcnt--;
116171095Ssam		uio->uio_iov++;
117171095Ssam		goto again;
118171095Ssam	}
119171095Ssam	switch (uio->uio_segflg) {
120171095Ssam
121171095Ssam	case UIO_USERSPACE:
122171095Ssam		if (subyte(iov->iov_base, c) < 0)
123171095Ssam			return (EFAULT);
124171095Ssam		break;
125171095Ssam
126171095Ssam	case UIO_SYSSPACE:
127171095Ssam		*iov->iov_base = c;
128171095Ssam		break;
129171095Ssam
130171095Ssam	case UIO_USERISPACE:
131171095Ssam		if (suibyte(iov->iov_base, c) < 0)
132171095Ssam			return (EFAULT);
133171095Ssam		break;
134171095Ssam	}
135171095Ssam	iov->iov_base++;
136171095Ssam	iov->iov_len--;
137171095Ssam	uio->uio_resid--;
138171095Ssam	uio->uio_offset++;
139171095Ssam	return (0);
140171095Ssam}
141171095Ssam
142171095Ssam#ifdef vax	/* unused except by ct.c, other oddities XXX */
143171095Ssam/*
144171095Ssam * Get next character written in by user from uio.
145171095Ssam */
146171095Ssamuwritec(uio)
147171095Ssam	struct uio *uio;
148171095Ssam{
149171095Ssam	register struct iovec *iov;
150171095Ssam	register int c;
151171095Ssam
152171095Ssam	if (uio->uio_resid <= 0)
153171095Ssam		return (-1);
154171095Ssamagain:
155171095Ssam	if (uio->uio_iovcnt <= 0)
156171095Ssam		panic("uwritec");
157171095Ssam	iov = uio->uio_iov;
158171095Ssam	if (iov->iov_len == 0) {
159171095Ssam		uio->uio_iov++;
160171095Ssam		if (--uio->uio_iovcnt == 0)
161171095Ssam			return (-1);
162171095Ssam		goto again;
163171095Ssam	}
164171095Ssam	switch (uio->uio_segflg) {
165171095Ssam
166171095Ssam	case UIO_USERSPACE:
167171095Ssam		c = fubyte(iov->iov_base);
168171095Ssam		break;
169171095Ssam
170171095Ssam	case UIO_SYSSPACE:
171171095Ssam		c = *(u_char *) iov->iov_base;
172171095Ssam		break;
173171095Ssam
174171095Ssam	case UIO_USERISPACE:
175171095Ssam		c = fuibyte(iov->iov_base);
176171095Ssam		break;
177171095Ssam	}
178171095Ssam	if (c < 0)
179171095Ssam		return (-1);
180171095Ssam	iov->iov_base++;
181171095Ssam	iov->iov_len--;
182171095Ssam	uio->uio_resid--;
183171095Ssam	uio->uio_offset++;
184171095Ssam	return (c);
185171095Ssam}
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