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