diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-11-11 13:57:58 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-11-11 13:57:58 +0000 |
commit | 228605dc7bfac86604166d5e3bbabb72ae40b78b (patch) | |
tree | 3f82c0349967d361fc5e1195a983ff7a227e02b1 /firmware/common | |
parent | 1e524abd5b8d8966341b4f98c68bd0ca2ac3775e (diff) | |
download | rockbox-228605dc7bfac86604166d5e3bbabb72ae40b78b.tar.gz rockbox-228605dc7bfac86604166d5e3bbabb72ae40b78b.zip |
Added support for O_RDWR and lseek() while writing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2826 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common')
-rw-r--r-- | firmware/common/file.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index d86609e470..b86938007b 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -38,11 +38,12 @@ | |||
38 | struct filedesc { | 38 | struct filedesc { |
39 | unsigned char cache[SECTOR_SIZE]; | 39 | unsigned char cache[SECTOR_SIZE]; |
40 | int cacheoffset; | 40 | int cacheoffset; |
41 | unsigned int fileoffset; | 41 | int fileoffset; |
42 | int size; | 42 | int size; |
43 | struct fat_file fatfile; | 43 | struct fat_file fatfile; |
44 | bool busy; | 44 | bool busy; |
45 | bool write; | 45 | bool write; |
46 | bool dirty; | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | static struct filedesc openfiles[MAX_OPEN_FILES]; | 49 | static struct filedesc openfiles[MAX_OPEN_FILES]; |
@@ -85,6 +86,7 @@ int open(const char* pathname, int flags) | |||
85 | openfiles[fd].write = false; | 86 | openfiles[fd].write = false; |
86 | break; | 87 | break; |
87 | 88 | ||
89 | case O_RDWR: | ||
88 | case O_WRONLY: | 90 | case O_WRONLY: |
89 | openfiles[fd].write = true; | 91 | openfiles[fd].write = true; |
90 | break; | 92 | break; |
@@ -168,7 +170,7 @@ int close(int fd) | |||
168 | } | 170 | } |
169 | if (openfiles[fd].write) { | 171 | if (openfiles[fd].write) { |
170 | /* flush sector cache */ | 172 | /* flush sector cache */ |
171 | if ( openfiles[fd].cacheoffset != -1 ) { | 173 | if ( openfiles[fd].dirty ) { |
172 | if ( fat_readwrite(&(openfiles[fd].fatfile), 1, | 174 | if ( fat_readwrite(&(openfiles[fd].fatfile), 1, |
173 | &(openfiles[fd].cache),true) < 0 ) { | 175 | &(openfiles[fd].cache),true) < 0 ) { |
174 | DEBUGF("Failed flushing cache\n"); | 176 | DEBUGF("Failed flushing cache\n"); |
@@ -250,12 +252,14 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
250 | int rc = fat_readwrite(&(openfiles[fd].fatfile), 1, | 252 | int rc = fat_readwrite(&(openfiles[fd].fatfile), 1, |
251 | openfiles[fd].cache, true ); | 253 | openfiles[fd].cache, true ); |
252 | if ( rc < 0 ) { | 254 | if ( rc < 0 ) { |
253 | DEBUGF("Failed read/writing\n"); | ||
254 | errno = EIO; | 255 | errno = EIO; |
255 | return -2; | 256 | return -2; |
256 | } | 257 | } |
258 | openfiles[fd].dirty = false; | ||
257 | openfiles[fd].cacheoffset = -1; | 259 | openfiles[fd].cacheoffset = -1; |
258 | } | 260 | } |
261 | else | ||
262 | openfiles[fd].dirty = true; | ||
259 | } | 263 | } |
260 | else { | 264 | else { |
261 | memcpy( buf, openfiles[fd].cache + offs, headbytes ); | 265 | memcpy( buf, openfiles[fd].cache + offs, headbytes ); |
@@ -265,6 +269,28 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
265 | count -= headbytes; | 269 | count -= headbytes; |
266 | } | 270 | } |
267 | 271 | ||
272 | /* if buffer has been modified, write it back to disk */ | ||
273 | if (count && openfiles[fd].dirty) { | ||
274 | int rc; | ||
275 | DEBUGF("Flushing dirty sector cache\n"); | ||
276 | |||
277 | /* seek back one sector to get file position right */ | ||
278 | rc = fat_seek(&(openfiles[fd].fatfile), | ||
279 | openfiles[fd].fileoffset / SECTOR_SIZE); | ||
280 | if ( rc < 0 ) { | ||
281 | errno = EIO; | ||
282 | return -3; | ||
283 | } | ||
284 | |||
285 | rc = fat_readwrite(&(openfiles[fd].fatfile), 1, | ||
286 | openfiles[fd].cache, true ); | ||
287 | if ( rc < 0 ) { | ||
288 | errno = EIO; | ||
289 | return -4; | ||
290 | } | ||
291 | openfiles[fd].dirty = false; | ||
292 | } | ||
293 | |||
268 | /* read whole sectors right into the supplied buffer */ | 294 | /* read whole sectors right into the supplied buffer */ |
269 | sectors = count / SECTOR_SIZE; | 295 | sectors = count / SECTOR_SIZE; |
270 | if ( sectors ) { | 296 | if ( sectors ) { |
@@ -273,7 +299,7 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
273 | if ( rc < 0 ) { | 299 | if ( rc < 0 ) { |
274 | DEBUGF("Failed read/writing %d sectors\n",sectors); | 300 | DEBUGF("Failed read/writing %d sectors\n",sectors); |
275 | errno = EIO; | 301 | errno = EIO; |
276 | return -3; | 302 | return -5; |
277 | } | 303 | } |
278 | else { | 304 | else { |
279 | if ( rc > 0 ) { | 305 | if ( rc > 0 ) { |
@@ -305,7 +331,7 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
305 | if ( rc < 0 ) { | 331 | if ( rc < 0 ) { |
306 | DEBUGF("Failed reading\n"); | 332 | DEBUGF("Failed reading\n"); |
307 | errno = EIO; | 333 | errno = EIO; |
308 | return -4; | 334 | return -6; |
309 | } | 335 | } |
310 | /* seek back one sector to put file position right */ | 336 | /* seek back one sector to put file position right */ |
311 | rc = fat_seek(&(openfiles[fd].fatfile), | 337 | rc = fat_seek(&(openfiles[fd].fatfile), |
@@ -314,17 +340,18 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
314 | if ( rc < 0 ) { | 340 | if ( rc < 0 ) { |
315 | DEBUGF("fat_seek() failed\n"); | 341 | DEBUGF("fat_seek() failed\n"); |
316 | errno = EIO; | 342 | errno = EIO; |
317 | return -5; | 343 | return -7; |
318 | } | 344 | } |
319 | } | 345 | } |
320 | memcpy( openfiles[fd].cache, buf + nread, count ); | 346 | memcpy( openfiles[fd].cache, buf + nread, count ); |
347 | openfiles[fd].dirty = true; | ||
321 | } | 348 | } |
322 | else { | 349 | else { |
323 | if ( fat_readwrite(&(openfiles[fd].fatfile), 1, | 350 | if ( fat_readwrite(&(openfiles[fd].fatfile), 1, |
324 | &(openfiles[fd].cache),false) < 1 ) { | 351 | &(openfiles[fd].cache),false) < 1 ) { |
325 | DEBUGF("Failed caching sector\n"); | 352 | DEBUGF("Failed caching sector\n"); |
326 | errno = EIO; | 353 | errno = EIO; |
327 | return -6; | 354 | return -8; |
328 | } | 355 | } |
329 | memcpy( buf + nread, openfiles[fd].cache, count ); | 356 | memcpy( buf + nread, openfiles[fd].cache, count ); |
330 | } | 357 | } |
@@ -345,6 +372,10 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
345 | 372 | ||
346 | int write(int fd, void* buf, int count) | 373 | int write(int fd, void* buf, int count) |
347 | { | 374 | { |
375 | if (!openfiles[fd].write) { | ||
376 | errno = EACCES; | ||
377 | return -1; | ||
378 | } | ||
348 | return readwrite(fd, buf, count, true); | 379 | return readwrite(fd, buf, count, true); |
349 | } | 380 | } |
350 | 381 | ||
@@ -369,13 +400,6 @@ int lseek(int fd, int offset, int whence) | |||
369 | return -1; | 400 | return -1; |
370 | } | 401 | } |
371 | 402 | ||
372 | if ( openfiles[fd].write ) { | ||
373 | DEBUGF("lseek() is not supported when writing\n"); | ||
374 | errno = EROFS; | ||
375 | return -2; | ||
376 | } | ||
377 | |||
378 | |||
379 | switch ( whence ) { | 403 | switch ( whence ) { |
380 | case SEEK_SET: | 404 | case SEEK_SET: |
381 | pos = offset; | 405 | pos = offset; |