1 /* ----------------------------------------------------------------------- * 2 * 3 * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved 4 * 5 * Permission is hereby granted, free of charge, to any person 6 * obtaining a copy of this software and associated documentation 7 * files (the "Software"), to deal in the Software without 8 * restriction, including without limitation the rights to use, 9 * copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom 11 * the Software is furnished to do so, subject to the following 12 * conditions: 13 * 14 * The above copyright notice and this permission notice shall 15 * be included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * ----------------------------------------------------------------------- */ 27 28 /* 29 * read.c 30 * 31 * Reading from a file 32 */ 33 34 #include <errno.h> 35 #include <string.h> 36 #include <com32.h> 37 #include <pmapi.h> 38 #include <syslinux/pmapi.h> 39 #include <minmax.h> 40 #include "file.h" 41 42 int __file_get_block(struct file_info *fp) 43 { 44 ssize_t bytes_read; 45 46 bytes_read = pmapi_read_file(&fp->i.fd.handle, fp->i.buf, 47 MAXBLOCK >> fp->i.fd.blocklg2); 48 if (!bytes_read) { 49 errno = EIO; 50 return -1; 51 } 52 53 fp->i.nbytes = bytes_read; 54 fp->i.datap = fp->i.buf; 55 return 0; 56 } 57 58 ssize_t __file_read(struct file_info * fp, void *buf, size_t count) 59 { 60 char *bufp = buf; 61 ssize_t n = 0; 62 size_t ncopy; 63 64 while (count) { 65 if (fp->i.nbytes == 0) { 66 if (fp->i.offset >= fp->i.fd.size || !fp->i.fd.handle) 67 return n; /* As good as it gets... */ 68 69 if (count > MAXBLOCK) { 70 /* Large transfer: copy directly, without buffering */ 71 ncopy = pmapi_read_file(&fp->i.fd.handle, bufp, 72 count >> fp->i.fd.blocklg2); 73 if (!ncopy) { 74 errno = EIO; 75 return n ? n : -1; 76 } 77 78 goto got_data; 79 } else { 80 if (__file_get_block(fp)) 81 return n ? n : -1; 82 } 83 } 84 85 ncopy = min(count, fp->i.nbytes); 86 memcpy(bufp, fp->i.datap, ncopy); 87 88 fp->i.datap += ncopy; 89 fp->i.offset += ncopy; 90 fp->i.nbytes -= ncopy; 91 92 got_data: 93 n += ncopy; 94 bufp += ncopy; 95 count -= ncopy; 96 } 97 98 return n; 99 } 100