summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-11-11 15:45:43 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-11-11 15:45:43 +0000
commit9f9c495662cbba43fdb3bf577a48d40e30e1245e (patch)
tree3915204f95071cefce7f8928113f389004d43a98 /firmware
parent68640edf90c84c3d4494f0852f6236e1929a4603 (diff)
downloadrockbox-9f9c495662cbba43fdb3bf577a48d40e30e1245e.tar.gz
rockbox-9f9c495662cbba43fdb3bf577a48d40e30e1245e.zip
Added support for O_CREAT, O_APPEND and O_TRUNC.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2828 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/common/file.c100
-rw-r--r--firmware/common/file.h3
2 files changed, 63 insertions, 40 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c
index cf8c46c5ab..82a33ada2d 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -44,14 +44,17 @@ struct filedesc {
44 bool busy; 44 bool busy;
45 bool write; 45 bool write;
46 bool dirty; 46 bool dirty;
47 bool trunc;
47}; 48};
48 49
49static struct filedesc openfiles[MAX_OPEN_FILES]; 50static struct filedesc openfiles[MAX_OPEN_FILES];
50 51
52static int flush_cache(int fd);
53
51int creat(const char *pathname, int mode) 54int creat(const char *pathname, int mode)
52{ 55{
53 (void)mode; 56 (void)mode;
54 return open(pathname, O_WRONLY); 57 return open(pathname, O_WRONLY|O_CREAT);
55} 58}
56 59
57int open(const char* pathname, int flags) 60int open(const char* pathname, int flags)
@@ -81,20 +84,16 @@ int open(const char* pathname, int flags)
81 return -2; 84 return -2;
82 } 85 }
83 86
84 switch ( flags ) { 87 if (flags & O_RDONLY) {
85 case O_RDONLY: 88 openfiles[fd].write = false;
86 openfiles[fd].write = false; 89 }
87 break; 90 else {
88 91 if (flags & (O_RDWR | O_WRONLY)) {
89 case O_RDWR:
90 case O_WRONLY:
91 openfiles[fd].write = true; 92 openfiles[fd].write = true;
92 break;
93 93
94 default: 94 if (flags & O_TRUNC)
95 DEBUGF("Only O_RDONLY and O_WRONLY is supported\n"); 95 openfiles[fd].trunc = true;
96 errno = EROFS; 96 }
97 return -3;
98 } 97 }
99 openfiles[fd].busy = true; 98 openfiles[fd].busy = true;
100 99
@@ -130,7 +129,7 @@ int open(const char* pathname, int flags)
130 closedir(dir); 129 closedir(dir);
131 if ( !entry ) { 130 if ( !entry ) {
132 LDEBUGF("Didn't find file %s\n",name); 131 LDEBUGF("Didn't find file %s\n",name);
133 if ( openfiles[fd].write ) { 132 if ( openfiles[fd].write && (flags & O_CREAT) ) {
134 if (fat_create_file(name, 133 if (fat_create_file(name,
135 &(openfiles[fd].fatfile), 134 &(openfiles[fd].fatfile),
136 &(dir->fatdir)) < 0) { 135 &(dir->fatdir)) < 0) {
@@ -151,6 +150,12 @@ int open(const char* pathname, int flags)
151 150
152 openfiles[fd].cacheoffset = -1; 151 openfiles[fd].cacheoffset = -1;
153 openfiles[fd].fileoffset = 0; 152 openfiles[fd].fileoffset = 0;
153
154 if (openfiles[fd].write && (flags & O_APPEND)) {
155 if (lseek(fd,0,SEEK_END) < 0 )
156 return -7;
157 }
158
154 return fd; 159 return fd;
155} 160}
156 161
@@ -169,18 +174,21 @@ int close(int fd)
169 return -2; 174 return -2;
170 } 175 }
171 if (openfiles[fd].write) { 176 if (openfiles[fd].write) {
177 /* truncate? */
178 if (openfiles[fd].trunc) {
179 if (ftruncate(fd, openfiles[fd].fileoffset) < 0)
180 return -1;
181 }
182
172 /* flush sector cache */ 183 /* flush sector cache */
173 if ( openfiles[fd].dirty ) { 184 if ( openfiles[fd].dirty ) {
174 if ( fat_readwrite(&(openfiles[fd].fatfile), 1, 185 if (flush_cache(fd) < 0)
175 &(openfiles[fd].cache),true) < 0 ) { 186 return -2;
176 DEBUGF("Failed flushing cache\n");
177 errno = EIO;
178 rc = -1;
179 }
180 } 187 }
181 188
182 /* tie up all loose ends */ 189 /* tie up all loose ends */
183 fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].size); 190 if (fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].size) < 0)
191 return -3;
184 } 192 }
185 openfiles[fd].busy = false; 193 openfiles[fd].busy = false;
186 return rc; 194 return rc;
@@ -239,6 +247,28 @@ int ftruncate(int fd, unsigned int size)
239 return 0; 247 return 0;
240} 248}
241 249
250static int flush_cache(int fd)
251{
252 int rc;
253 int sector = openfiles[fd].fileoffset / SECTOR_SIZE;
254
255 DEBUGF("Flushing dirty sector cache %x\n", sector);
256
257 /* seek back one sector to get file position right */
258 rc = fat_seek(&(openfiles[fd].fatfile), sector);
259 if ( rc < 0 )
260 return -1;
261
262 rc = fat_readwrite(&(openfiles[fd].fatfile), 1,
263 openfiles[fd].cache, true );
264 if ( rc < 0 )
265 return -2;
266
267 openfiles[fd].dirty = false;
268
269 return 0;
270}
271
242static int readwrite(int fd, void* buf, int count, bool write) 272static int readwrite(int fd, void* buf, int count, bool write)
243{ 273{
244 int sectors; 274 int sectors;
@@ -296,24 +326,8 @@ static int readwrite(int fd, void* buf, int count, bool write)
296 326
297 /* if buffer has been modified, write it back to disk */ 327 /* if buffer has been modified, write it back to disk */
298 if (count && openfiles[fd].dirty) { 328 if (count && openfiles[fd].dirty) {
299 int rc; 329 if (flush_cache(fd) < 0)
300 DEBUGF("Flushing dirty sector cache\n");
301
302 /* seek back one sector to get file position right */
303 rc = fat_seek(&(openfiles[fd].fatfile),
304 openfiles[fd].fileoffset / SECTOR_SIZE);
305 if ( rc < 0 ) {
306 errno = EIO;
307 return -3; 330 return -3;
308 }
309
310 rc = fat_readwrite(&(openfiles[fd].fatfile), 1,
311 openfiles[fd].cache, true );
312 if ( rc < 0 ) {
313 errno = EIO;
314 return -4;
315 }
316 openfiles[fd].dirty = false;
317 } 331 }
318 332
319 /* read whole sectors right into the supplied buffer */ 333 /* read whole sectors right into the supplied buffer */
@@ -454,7 +468,13 @@ int lseek(int fd, int offset, int whence)
454 468
455 if ( (newsector != oldsector) || 469 if ( (newsector != oldsector) ||
456 ((openfiles[fd].cacheoffset==-1) && sectoroffset) ) { 470 ((openfiles[fd].cacheoffset==-1) && sectoroffset) ) {
471
457 if ( newsector != oldsector ) { 472 if ( newsector != oldsector ) {
473 if (openfiles[fd].dirty) {
474 if (flush_cache(fd) < 0)
475 return -5;
476 }
477
458 rc = fat_seek(&(openfiles[fd].fatfile), newsector); 478 rc = fat_seek(&(openfiles[fd].fatfile), newsector);
459 if ( rc < 0 ) { 479 if ( rc < 0 ) {
460 errno = EIO; 480 errno = EIO;
@@ -466,7 +486,7 @@ int lseek(int fd, int offset, int whence)
466 &(openfiles[fd].cache),false); 486 &(openfiles[fd].cache),false);
467 if ( rc < 0 ) { 487 if ( rc < 0 ) {
468 errno = EIO; 488 errno = EIO;
469 return -5; 489 return -6;
470 } 490 }
471 openfiles[fd].cacheoffset = sectoroffset; 491 openfiles[fd].cacheoffset = sectoroffset;
472 } 492 }
diff --git a/firmware/common/file.h b/firmware/common/file.h
index 59ff717d1d..2effe31ac9 100644
--- a/firmware/common/file.h
+++ b/firmware/common/file.h
@@ -37,6 +37,9 @@
37#define O_RDONLY 0 37#define O_RDONLY 0
38#define O_WRONLY 1 38#define O_WRONLY 1
39#define O_RDWR 2 39#define O_RDWR 2
40#define O_CREAT 3
41#define O_APPEND 4
42#define O_TRUNC 5
40#endif 43#endif
41 44
42#if defined(__MINGW32__) && defined(SIMULATOR) 45#if defined(__MINGW32__) && defined(SIMULATOR)