summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-05-08 12:10:30 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-05-08 12:10:30 +0000
commit073ce1aab3ac73e0b434acd8b5dedee40eab79e4 (patch)
treeaadf3ac47121a2b2d1353e4069fc4b6a668e1f88 /firmware/common
parent7dd442b7c36f43e3593905d86283f707b0b2dfe1 (diff)
downloadrockbox-073ce1aab3ac73e0b434acd8b5dedee40eab79e4.tar.gz
rockbox-073ce1aab3ac73e0b434acd8b5dedee40eab79e4.zip
Fixed read() for sub-sector requests
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@513 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common')
-rw-r--r--firmware/common/file.c108
1 files changed, 70 insertions, 38 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 86e1099918..41aaea570a 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -17,6 +17,7 @@
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#include <string.h> 19#include <string.h>
20#include <errno.h>
20#include "file.h" 21#include "file.h"
21#include "fat.h" 22#include "fat.h"
22#include "types.h" 23#include "types.h"
@@ -26,8 +27,10 @@
26#define MAX_OPEN_FILES 4 27#define MAX_OPEN_FILES 4
27 28
28struct filedesc { 29struct filedesc {
29 unsigned char sector[SECTOR_SIZE]; 30 unsigned char cache[SECTOR_SIZE];
30 int offset; 31 int cacheoffset;
32 int fileoffset;
33 int size;
31 struct fat_file fatfile; 34 struct fat_file fatfile;
32 bool busy; 35 bool busy;
33}; 36};
@@ -45,6 +48,7 @@ int open(char* pathname, int flags)
45 if ( pathname[0] != '/' ) { 48 if ( pathname[0] != '/' ) {
46 DEBUGF("'%s' is not an absolute path.\n",pathname); 49 DEBUGF("'%s' is not an absolute path.\n",pathname);
47 DEBUGF("Only absolute pathnames supported at the moment\n"); 50 DEBUGF("Only absolute pathnames supported at the moment\n");
51 errno = EINVAL;
48 return -1; 52 return -1;
49 } 53 }
50 54
@@ -55,6 +59,7 @@ int open(char* pathname, int flags)
55 59
56 if ( fd == MAX_OPEN_FILES ) { 60 if ( fd == MAX_OPEN_FILES ) {
57 DEBUGF("Too many files open\n"); 61 DEBUGF("Too many files open\n");
62 errno = EMFILE;
58 return -1; 63 return -1;
59 } 64 }
60 65
@@ -72,6 +77,7 @@ int open(char* pathname, int flags)
72 } 77 }
73 if (!dir) { 78 if (!dir) {
74 DEBUGF("Failed opening dir\n"); 79 DEBUGF("Failed opening dir\n");
80 errno = EIO;
75 return -1; 81 return -1;
76 } 82 }
77 83
@@ -80,6 +86,7 @@ int open(char* pathname, int flags)
80 while ((entry = readdir(dir))) { 86 while ((entry = readdir(dir))) {
81 if ( !strncmp(name, entry->d_name, namelen) ) { 87 if ( !strncmp(name, entry->d_name, namelen) ) {
82 fat_open(entry->startcluster, &(openfiles[fd].fatfile)); 88 fat_open(entry->startcluster, &(openfiles[fd].fatfile));
89 openfiles[fd].size = entry->size;
83 break; 90 break;
84 } 91 }
85 else { 92 else {
@@ -89,11 +96,12 @@ int open(char* pathname, int flags)
89 closedir(dir); 96 closedir(dir);
90 if ( !entry ) { 97 if ( !entry ) {
91 DEBUGF("Couldn't find %s in %s\n",name,pathname); 98 DEBUGF("Couldn't find %s in %s\n",name,pathname);
92 /* fixme: we need to use proper error codes */ 99 errno = ENOENT;
93 return -1; 100 return -1;
94 } 101 }
95 102
96 openfiles[fd].offset = 0; 103 openfiles[fd].cacheoffset = 0;
104 openfiles[fd].fileoffset = 0;
97 openfiles[fd].busy = TRUE; 105 openfiles[fd].busy = TRUE;
98 return fd; 106 return fd;
99} 107}
@@ -109,57 +117,81 @@ int read(int fd, void* buf, int count)
109 int sectors; 117 int sectors;
110 int nread=0; 118 int nread=0;
111 119
112 /* are we in the middle of a cached sector? */ 120 if ( !openfiles[fd].busy ) {
113 if ( openfiles[fd].offset ) { 121 errno = EBADF;
114 if ( count > (SECTOR_SIZE - openfiles[fd].offset) ) { 122 return -1;
115 memcpy( buf, openfiles[fd].sector, 123 }
116 SECTOR_SIZE - openfiles[fd].offset ); 124
117 openfiles[fd].offset = 0; 125 /* attempt to read past EOF? */
118 nread = SECTOR_SIZE - openfiles[fd].offset; 126 if ( count > openfiles[fd].size - openfiles[fd].fileoffset )
119 count -= nread; 127 count = openfiles[fd].size - openfiles[fd].fileoffset;
128
129 /* any head bytes? */
130 if ( openfiles[fd].cacheoffset ) {
131 int headbytes;
132 int offs = openfiles[fd].cacheoffset;
133 if ( count <= SECTOR_SIZE - openfiles[fd].cacheoffset ) {
134 headbytes = count;
135 openfiles[fd].cacheoffset += count;
136 if ( openfiles[fd].cacheoffset >= SECTOR_SIZE )
137 openfiles[fd].cacheoffset = 0;
120 } 138 }
121 else { 139 else {
122 memcpy( buf, openfiles[fd].sector, count ); 140 headbytes = SECTOR_SIZE - openfiles[fd].cacheoffset;
123 openfiles[fd].offset += count; 141 openfiles[fd].cacheoffset = 0;
124 nread = count;
125 count = 0;
126 } 142 }
143
144 /* eof? */
145 if ( openfiles[fd].fileoffset + headbytes > openfiles[fd].size )
146 headbytes = openfiles[fd].size - openfiles[fd].fileoffset;
147
148 memcpy( buf, openfiles[fd].cache + offs, headbytes );
149 nread = headbytes;
150 count -= headbytes;
127 } 151 }
128 152
129 /* read whole sectors right into the supplied buffer */ 153 /* read whole sectors right into the supplied buffer */
130 sectors = count / SECTOR_SIZE; 154 sectors = count / SECTOR_SIZE;
131 if ( sectors ) { 155 if ( sectors ) {
132 if ( fat_read(&(openfiles[fd].fatfile), sectors, buf+nread ) < 0 ) { 156 int rc = fat_read(&(openfiles[fd].fatfile), sectors, buf+nread );
157 if ( rc < 0 ) {
133 DEBUGF("Failed reading %d sectors\n",sectors); 158 DEBUGF("Failed reading %d sectors\n",sectors);
159 errno = EIO;
134 return -1; 160 return -1;
135 } 161 }
136 nread += sectors * SECTOR_SIZE; 162 else {
137 count -= sectors * SECTOR_SIZE; 163 if ( rc > 0 ) {
138 openfiles[fd].offset = 0; 164 nread += sectors * SECTOR_SIZE;
165 count -= sectors * SECTOR_SIZE;
166 }
167 else {
168 /* eof */
169 count=0;
170 }
171
172 openfiles[fd].cacheoffset = 0;
173 }
139 } 174 }
140 175
141 /* trailing odd bytes? */ 176 /* any tail bytes? */
142 if ( count ) { 177 if ( count ) {
143 /* do we already have the sector cached? */ 178 if ( fat_read(&(openfiles[fd].fatfile), 1,
144 if ( count < (SECTOR_SIZE - openfiles[fd].offset) ) { 179 &(openfiles[fd].cache)) < 0 ) {
145 memcpy( buf + nread, openfiles[fd].sector, count ); 180 DEBUGF("Failed caching sector\n");
146 openfiles[fd].offset += count; 181 errno = EIO;
147 nread += count; 182 return -1;
148 count = 0;
149 }
150 else {
151 /* cache one sector and copy the trailing bytes */
152 if ( fat_read(&(openfiles[fd].fatfile), 1,
153 &(openfiles[fd].sector)) < 0 ) {
154 DEBUGF("Failed reading odd sector\n");
155 return -1;
156 }
157 memcpy( buf + nread, openfiles[fd].sector, count );
158 openfiles[fd].offset = nread;
159 nread += count;
160 } 183 }
184
185 /* eof? */
186 if ( openfiles[fd].fileoffset + count > openfiles[fd].size )
187 count = openfiles[fd].size - openfiles[fd].fileoffset;
188
189 memcpy( buf + nread, openfiles[fd].cache, count );
190 nread += count;
191 openfiles[fd].cacheoffset = count;
161 } 192 }
162 193
194 openfiles[fd].fileoffset += nread;
163 return nread; 195 return nread;
164} 196}
165 197