1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * University Copyright- Copyright (c) 1982, 1986, 1988 31 * The Regents of the University of California 32 * All Rights Reserved 33 * 34 * University Acknowledgment- Portions of this document are derived from 35 * software developed by the University of California, Berkeley, and its 36 * contributors. 37 */ 38 39 /* 40 * $FreeBSD$ 41 */ 42 43 #include <sys/types.h> 44 #include <sys/uio.h> 45 46 /* 47 * same as uiomove() but doesn't modify uio structure. 48 * return in cbytes how many bytes were copied. 49 */ 50 int 51 uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes) 52 { 53 struct iovec *iov; 54 ulong_t cnt; 55 int error, iovcnt; 56 57 iovcnt = uio->uio_iovcnt; 58 *cbytes = 0; 59 60 for (iov = uio->uio_iov; n > 0 && iovcnt > 0; iov++, iovcnt--) { 61 cnt = MIN(iov->iov_len, n); 62 if (cnt == 0) 63 continue; 64 65 switch (uio->uio_segflg) { 66 case UIO_USERSPACE: 67 if (rw == UIO_READ) 68 error = copyout(p, iov->iov_base, cnt); 69 else 70 error = copyin(iov->iov_base, p, cnt); 71 if (error) 72 return (error); 73 break; 74 case UIO_SYSSPACE: 75 if (uio->uio_rw == UIO_READ) 76 bcopy(p, iov->iov_base, cnt); 77 else 78 bcopy(iov->iov_base, p, cnt); 79 break; 80 } 81 82 p = (caddr_t)p + cnt; 83 n -= cnt; 84 *cbytes += cnt; 85 } 86 return (0); 87 } 88 89 /* 90 * Drop the next n chars out of *uiop. 91 */ 92 void 93 uioskip(uio_t *uiop, size_t n) 94 { 95 if (n > uiop->uio_resid) 96 return; 97 while (n != 0) { 98 register iovec_t *iovp = uiop->uio_iov; 99 register size_t niovb = MIN(iovp->iov_len, n); 100 101 if (niovb == 0) { 102 uiop->uio_iov++; 103 uiop->uio_iovcnt--; 104 continue; 105 } 106 iovp->iov_base += niovb; 107 uiop->uio_loffset += niovb; 108 iovp->iov_len -= niovb; 109 uiop->uio_resid -= niovb; 110 n -= niovb; 111 } 112 } 113