summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-11-11 13:57:58 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-11-11 13:57:58 +0000
commit228605dc7bfac86604166d5e3bbabb72ae40b78b (patch)
tree3f82c0349967d361fc5e1195a983ff7a227e02b1 /firmware
parent1e524abd5b8d8966341b4f98c68bd0ca2ac3775e (diff)
downloadrockbox-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')
-rw-r--r--firmware/common/file.c52
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 @@
38struct filedesc { 38struct 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
48static struct filedesc openfiles[MAX_OPEN_FILES]; 49static 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
346int write(int fd, void* buf, int count) 373int 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;