read.c revision 136093
138032Speter/* $NetBSD: read.c,v 1.8 1997/01/22 00:38:12 cgd Exp $ */ 2244833Sgshapiro 364562Sgshapiro/*- 438032Speter * Copyright (c) 1993 538032Speter * The Regents of the University of California. All rights reserved. 638032Speter * 738032Speter * This code is derived from software contributed to Berkeley by 838032Speter * The Mach Operating System project at Carnegie-Mellon University. 938032Speter * 1038032Speter * Redistribution and use in source and binary forms, with or without 1138032Speter * modification, are permitted provided that the following conditions 1238032Speter * are met: 1338032Speter * 1. Redistributions of source code must retain the above copyright 1464562Sgshapiro * notice, this list of conditions and the following disclaimer. 15147078Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright 1664562Sgshapiro * notice, this list of conditions and the following disclaimer in the 17249729Sgshapiro * documentation and/or other materials provided with the distribution. 1838032Speter * 3. All advertising materials mentioning features or use of this software 1990792Sgshapiro * must display the following acknowledgement: 2038032Speter * This product includes software developed by the University of 2190792Sgshapiro * California, Berkeley and its contributors. 2290792Sgshapiro * 4. Neither the name of the University nor the names of its contributors 2390792Sgshapiro * may be used to endorse or promote products derived from this software 24120256Sgshapiro * without specific prior written permission. 2590792Sgshapiro * 26125820Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27125820Sgshapiro * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28125820Sgshapiro * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29125820Sgshapiro * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30125820Sgshapiro * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31125820Sgshapiro * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32120256Sgshapiro * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33125820Sgshapiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34125820Sgshapiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35125820Sgshapiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36125820Sgshapiro * SUCH DAMAGE. 3790792Sgshapiro * 3890792Sgshapiro * @(#)read.c 8.1 (Berkeley) 6/11/93 39120256Sgshapiro * 40120256Sgshapiro * 41132943Sgshapiro * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University 42132943Sgshapiro * All Rights Reserved. 43132943Sgshapiro * 4490792Sgshapiro * Author: Alessandro Forin 4590792Sgshapiro * 46132943Sgshapiro * Permission to use, copy, modify and distribute this software and its 47132943Sgshapiro * documentation is hereby granted, provided that both the copyright 4890792Sgshapiro * notice and this permission notice appear in all copies of the 4990792Sgshapiro * software, derivative works or modified versions, and any portions 5064562Sgshapiro * thereof, and that both notices appear in supporting documentation. 5190792Sgshapiro * 5290792Sgshapiro * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 5338032Speter * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 5438032Speter * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 5538032Speter * 5638032Speter * Carnegie Mellon requests users of this software to return to 5738032Speter * 5838032Speter * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 5938032Speter * School of Computer Science 6038032Speter * Carnegie Mellon University 6138032Speter * Pittsburgh PA 15213-3890 6238032Speter * 6338032Speter * any improvements or extensions that they make and grant Carnegie the 6490792Sgshapiro * rights to redistribute these changes. 6590792Sgshapiro */ 6690792Sgshapiro 6790792Sgshapiro#include <sys/cdefs.h> 6838032Speter__FBSDID("$FreeBSD: head/lib/libstand/read.c 136093 2004-10-03 15:58:20Z stefanf $"); 6938032Speter 7038032Speter#include <sys/param.h> 7138032Speter#include "stand.h" 7238032Speter 7390792Sgshapirossize_t 7490792Sgshapiroread(int fd, void *dest, size_t bcount) 75120256Sgshapiro{ 7638032Speter struct open_file *f = &files[fd]; 77120256Sgshapiro size_t resid; 78120256Sgshapiro 79120256Sgshapiro if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) { 80120256Sgshapiro errno = EBADF; 81120256Sgshapiro return (-1); 82120256Sgshapiro } 83120256Sgshapiro if (f->f_flags & F_RAW) { 84120256Sgshapiro twiddle(); 85120256Sgshapiro errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, 86120256Sgshapiro btodb(f->f_offset), bcount, dest, &resid); 87120256Sgshapiro if (errno) 88120256Sgshapiro return (-1); 89120256Sgshapiro f->f_offset += resid; 90120256Sgshapiro return (resid); 9190792Sgshapiro } 9294334Sgshapiro 9394334Sgshapiro /* 9490792Sgshapiro * Optimise reads from regular files using a readahead buffer. 9590792Sgshapiro * If the request can't be satisfied from the current buffer contents, 96111823Sgshapiro * check to see if it should be bypassed, or refill the buffer and complete 9790792Sgshapiro * the request. 9890792Sgshapiro */ 9990792Sgshapiro resid = bcount; 10090792Sgshapiro for (;;) { 10190792Sgshapiro size_t ccount, cresid; 10290792Sgshapiro /* how much can we supply? */ 10390792Sgshapiro ccount = imin(f->f_ralen, resid); 10490792Sgshapiro if (ccount > 0) { 10590792Sgshapiro bcopy(f->f_rabuf + f->f_raoffset, dest, ccount); 10690792Sgshapiro f->f_raoffset += ccount; 10790792Sgshapiro f->f_ralen -= ccount; 10890792Sgshapiro resid -= ccount; 10990792Sgshapiro if (resid == 0) 11090792Sgshapiro return(bcount); 11190792Sgshapiro dest = (char *)dest + ccount; 11290792Sgshapiro } 11390792Sgshapiro 11490792Sgshapiro /* will filling the readahead buffer again not help? */ 11590792Sgshapiro if (resid >= SOPEN_RASIZE) { 11690792Sgshapiro /* bypass the rest of the request and leave the buffer empty */ 11790792Sgshapiro if ((errno = (f->f_ops->fo_read)(f, dest, resid, &cresid))) 11890792Sgshapiro return (-1); 11990792Sgshapiro return(bcount - cresid); 12090792Sgshapiro } 12190792Sgshapiro 12290792Sgshapiro /* fetch more data */ 12390792Sgshapiro if ((errno = (f->f_ops->fo_read)(f, f->f_rabuf, SOPEN_RASIZE, &cresid))) 12490792Sgshapiro return (-1); 12590792Sgshapiro f->f_raoffset = 0; 12690792Sgshapiro f->f_ralen = SOPEN_RASIZE - cresid; 12790792Sgshapiro /* no more data, return what we had */ 12890792Sgshapiro if (f->f_ralen == 0) 12990792Sgshapiro return(bcount - resid); 13090792Sgshapiro } 13190792Sgshapiro} 13290792Sgshapiro