1209962Smm/*
2209962Smm * CDDL HEADER START
3209962Smm *
4209962Smm * The contents of this file are subject to the terms of the
5209962Smm * Common Development and Distribution License (the "License").
6209962Smm * You may not use this file except in compliance with the License.
7209962Smm *
8209962Smm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9209962Smm * or http://www.opensolaris.org/os/licensing.
10209962Smm * See the License for the specific language governing permissions
11209962Smm * and limitations under the License.
12209962Smm *
13209962Smm * When distributing Covered Code, include this CDDL HEADER in each
14209962Smm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15209962Smm * If applicable, add the following below this CDDL HEADER, with the
16209962Smm * fields enclosed by brackets "[]" replaced with your own identifying
17209962Smm * information: Portions Copyright [yyyy] [name of copyright owner]
18209962Smm *
19209962Smm * CDDL HEADER END
20209962Smm */
21209962Smm/*
22209962Smm * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23209962Smm * Use is subject to license terms.
24209962Smm */
25209962Smm
26209962Smm/*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27209962Smm/*        All Rights Reserved   */
28209962Smm
29209962Smm/*
30209962Smm * University Copyright- Copyright (c) 1982, 1986, 1988
31209962Smm * The Regents of the University of California
32209962Smm * All Rights Reserved
33209962Smm *
34209962Smm * University Acknowledgment- Portions of this document are derived from
35209962Smm * software developed by the University of California, Berkeley, and its
36209962Smm * contributors.
37209962Smm */
38209962Smm
39209962Smm/*
40209962Smm * $FreeBSD$
41209962Smm */
42209962Smm
43209962Smm#include <sys/types.h>
44209962Smm#include <sys/uio.h>
45209962Smm
46209962Smm/*
47209962Smm * same as uiomove() but doesn't modify uio structure.
48209962Smm * return in cbytes how many bytes were copied.
49209962Smm */
50209962Smmint
51209962Smmuiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes)
52209962Smm{
53209962Smm	struct iovec *iov;
54209962Smm	ulong_t cnt;
55209962Smm	int error, iovcnt;
56209962Smm
57209962Smm	iovcnt = uio->uio_iovcnt;
58209962Smm	*cbytes = 0;
59209962Smm
60209962Smm	for (iov = uio->uio_iov; n > 0 && iovcnt > 0; iov++, iovcnt--) {
61209962Smm		cnt = MIN(iov->iov_len, n);
62209962Smm		if (cnt == 0)
63209962Smm			continue;
64209962Smm
65209962Smm		switch (uio->uio_segflg) {
66209962Smm		case UIO_USERSPACE:
67209962Smm			if (rw == UIO_READ)
68209962Smm				error = copyout(p, iov->iov_base, cnt);
69209962Smm			else
70209962Smm				error = copyin(iov->iov_base, p, cnt);
71209962Smm			if (error)
72209962Smm				return (error);
73209962Smm			break;
74209962Smm		case UIO_SYSSPACE:
75209962Smm			if (uio->uio_rw == UIO_READ)
76209962Smm				bcopy(p, iov->iov_base, cnt);
77209962Smm			else
78209962Smm				bcopy(iov->iov_base, p, cnt);
79209962Smm			break;
80209962Smm		}
81209962Smm
82209962Smm		p = (caddr_t)p + cnt;
83209962Smm		n -= cnt;
84209962Smm		*cbytes += cnt;
85209962Smm	}
86209962Smm	return (0);
87209962Smm}
88209962Smm
89209962Smm/*
90209962Smm * Drop the next n chars out of *uiop.
91209962Smm */
92209962Smmvoid
93209962Smmuioskip(uio_t *uiop, size_t n)
94209962Smm{
95209962Smm	if (n > uiop->uio_resid)
96209962Smm		return;
97209962Smm	while (n != 0) {
98209962Smm		register iovec_t	*iovp = uiop->uio_iov;
99209962Smm		register size_t		niovb = MIN(iovp->iov_len, n);
100209962Smm
101209962Smm		if (niovb == 0) {
102209962Smm			uiop->uio_iov++;
103209962Smm			uiop->uio_iovcnt--;
104209962Smm			continue;
105209962Smm		}
106209962Smm		iovp->iov_base += niovb;
107209962Smm		uiop->uio_loffset += niovb;
108209962Smm		iovp->iov_len -= niovb;
109209962Smm		uiop->uio_resid -= niovb;
110209962Smm		n -= niovb;
111209962Smm	}
112209962Smm}
113