diff options
-rw-r--r-- | firmware/common/file.c | 27 | ||||
-rw-r--r-- | firmware/common/file.h | 1 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 9 |
3 files changed, 33 insertions, 4 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index b86938007b..cf8c46c5ab 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -90,7 +90,7 @@ int open(const char* pathname, int flags) | |||
90 | case O_WRONLY: | 90 | case O_WRONLY: |
91 | openfiles[fd].write = true; | 91 | openfiles[fd].write = true; |
92 | break; | 92 | break; |
93 | 93 | ||
94 | default: | 94 | default: |
95 | DEBUGF("Only O_RDONLY and O_WRONLY is supported\n"); | 95 | DEBUGF("Only O_RDONLY and O_WRONLY is supported\n"); |
96 | errno = EROFS; | 96 | errno = EROFS; |
@@ -214,6 +214,31 @@ int remove(const char* name) | |||
214 | return rc; | 214 | return rc; |
215 | } | 215 | } |
216 | 216 | ||
217 | int ftruncate(int fd, unsigned int size) | ||
218 | { | ||
219 | int rc, sector; | ||
220 | |||
221 | sector = size / SECTOR_SIZE; | ||
222 | if (size % SECTOR_SIZE) | ||
223 | sector++; | ||
224 | |||
225 | rc = fat_seek(&(openfiles[fd].fatfile), sector); | ||
226 | if (rc < 0) { | ||
227 | errno = EIO; | ||
228 | return -1; | ||
229 | } | ||
230 | |||
231 | rc = fat_truncate(&(openfiles[fd].fatfile)); | ||
232 | if (rc < 0) { | ||
233 | errno = EIO; | ||
234 | return -2; | ||
235 | } | ||
236 | |||
237 | openfiles[fd].size = size; | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
217 | static int readwrite(int fd, void* buf, int count, bool write) | 242 | static int readwrite(int fd, void* buf, int count, bool write) |
218 | { | 243 | { |
219 | int sectors; | 244 | int sectors; |
diff --git a/firmware/common/file.h b/firmware/common/file.h index 7a7c63d665..59ff717d1d 100644 --- a/firmware/common/file.h +++ b/firmware/common/file.h | |||
@@ -56,6 +56,7 @@ extern int creat(const char *pathname, int mode); | |||
56 | extern int write(int fd, void* buf, int count); | 56 | extern int write(int fd, void* buf, int count); |
57 | extern int remove(const char* pathname); | 57 | extern int remove(const char* pathname); |
58 | extern int rename(const char* oldname, const char* newname); | 58 | extern int rename(const char* oldname, const char* newname); |
59 | extern int ftruncate(int fd, unsigned int size); | ||
59 | 60 | ||
60 | #else | 61 | #else |
61 | #ifdef WIN32 | 62 | #ifdef WIN32 |
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 74bdbd3491..ad1a7a0c82 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -1002,12 +1002,15 @@ int fat_truncate(struct fat_file *file) | |||
1002 | { | 1002 | { |
1003 | /* truncate trailing clusters */ | 1003 | /* truncate trailing clusters */ |
1004 | int next; | 1004 | int next; |
1005 | int last = get_next_cluster(file->lastcluster); | 1005 | int last = file->lastcluster; |
1006 | while ( last && last != FAT_EOF_MARK ) { | 1006 | |
1007 | LDEBUGF("fat_truncate(%x, %x)\n", file->firstcluster, last); | ||
1008 | |||
1009 | for ( last = get_next_cluster(last); last; last = next ) { | ||
1007 | next = get_next_cluster(last); | 1010 | next = get_next_cluster(last); |
1008 | update_fat_entry(last,0); | 1011 | update_fat_entry(last,0); |
1009 | last = next; | ||
1010 | } | 1012 | } |
1013 | update_fat_entry(file->lastcluster,FAT_EOF_MARK); | ||
1011 | 1014 | ||
1012 | return 0; | 1015 | return 0; |
1013 | } | 1016 | } |