diff options
Diffstat (limited to 'firmware/common/file.c')
-rw-r--r-- | firmware/common/file.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index 1dd71d98ae..b2c2644725 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -38,7 +38,7 @@ | |||
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 | int fileoffset; | 41 | unsigned int fileoffset; |
42 | int size; | 42 | int size; |
43 | struct fat_file fatfile; | 43 | struct fat_file fatfile; |
44 | bool busy; | 44 | bool busy; |
@@ -178,7 +178,7 @@ int close(int fd) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | /* tie up all loose ends */ | 180 | /* tie up all loose ends */ |
181 | fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].fileoffset); | 181 | fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].size); |
182 | } | 182 | } |
183 | openfiles[fd].busy = false; | 183 | openfiles[fd].busy = false; |
184 | return rc; | 184 | return rc; |
@@ -191,7 +191,21 @@ int remove(const char* name) | |||
191 | if ( fd < 0 ) | 191 | if ( fd < 0 ) |
192 | return fd; | 192 | return fd; |
193 | 193 | ||
194 | rc = fat_truncate(&(openfiles[fd].fatfile)); | ||
195 | if ( rc < 0 ) { | ||
196 | DEBUGF("Failed truncating file\n"); | ||
197 | errno = EIO; | ||
198 | return -1; | ||
199 | } | ||
200 | |||
194 | rc = fat_remove(&(openfiles[fd].fatfile)); | 201 | rc = fat_remove(&(openfiles[fd].fatfile)); |
202 | if ( rc < 0 ) { | ||
203 | DEBUGF("Failed removing file\n"); | ||
204 | errno = EIO; | ||
205 | return -2; | ||
206 | } | ||
207 | |||
208 | openfiles[fd].size = 0; | ||
195 | 209 | ||
196 | close(fd); | 210 | close(fd); |
197 | 211 | ||
@@ -259,7 +273,7 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
259 | if ( rc < 0 ) { | 273 | if ( rc < 0 ) { |
260 | DEBUGF("Failed read/writing %d sectors\n",sectors); | 274 | DEBUGF("Failed read/writing %d sectors\n",sectors); |
261 | errno = EIO; | 275 | errno = EIO; |
262 | return -2; | 276 | return -3; |
263 | } | 277 | } |
264 | else { | 278 | else { |
265 | if ( rc > 0 ) { | 279 | if ( rc > 0 ) { |
@@ -278,10 +292,30 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
278 | openfiles[fd].cacheoffset = -1; | 292 | openfiles[fd].cacheoffset = -1; |
279 | } | 293 | } |
280 | } | 294 | } |
295 | openfiles[fd].fileoffset += nread; | ||
296 | nread = 0; | ||
281 | 297 | ||
282 | /* any tail bytes? */ | 298 | /* any tail bytes? */ |
283 | if ( count ) { | 299 | if ( count ) { |
284 | if (write) { | 300 | if (write) { |
301 | /* sector is only partially filled. copy-back from disk */ | ||
302 | int rc; | ||
303 | LDEBUGF("Copy-back tail cache\n"); | ||
304 | rc = fat_readwrite(&(openfiles[fd].fatfile), 1, | ||
305 | openfiles[fd].cache, false ); | ||
306 | if ( rc < 0 ) { | ||
307 | DEBUGF("Failed reading\n"); | ||
308 | errno = EIO; | ||
309 | return -4; | ||
310 | } | ||
311 | /* seek back one sector to put file position right */ | ||
312 | rc = fat_seek(&(openfiles[fd].fatfile), | ||
313 | openfiles[fd].fileoffset / SECTOR_SIZE); | ||
314 | if ( rc < 0 ) { | ||
315 | DEBUGF("fat_seek() failed\n"); | ||
316 | errno = EIO; | ||
317 | return -5; | ||
318 | } | ||
285 | memcpy( openfiles[fd].cache, buf + nread, count ); | 319 | memcpy( openfiles[fd].cache, buf + nread, count ); |
286 | } | 320 | } |
287 | else { | 321 | else { |
@@ -289,7 +323,7 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
289 | &(openfiles[fd].cache),false) < 1 ) { | 323 | &(openfiles[fd].cache),false) < 1 ) { |
290 | DEBUGF("Failed caching sector\n"); | 324 | DEBUGF("Failed caching sector\n"); |
291 | errno = EIO; | 325 | errno = EIO; |
292 | return -1; | 326 | return -6; |
293 | } | 327 | } |
294 | memcpy( buf + nread, openfiles[fd].cache, count ); | 328 | memcpy( buf + nread, openfiles[fd].cache, count ); |
295 | } | 329 | } |