diff options
-rw-r--r-- | firmware/common/file.c | 38 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 35 | ||||
-rw-r--r-- | firmware/export/fat.h | 2 | ||||
-rw-r--r-- | firmware/include/file.h | 3 | ||||
-rw-r--r-- | firmware/include/filesystem-native.h | 3 | ||||
-rw-r--r-- | firmware/libc/include/time.h | 6 |
6 files changed, 87 insertions, 0 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index cb918c6eab..c090c40be5 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -1123,6 +1123,44 @@ file_error: | |||
1123 | return rc; | 1123 | return rc; |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | int utime(const char *path, const struct utimbuf* times) | ||
1127 | { | ||
1128 | DEBUGF("utime(path=\"%s\",times->modtime=%u)\n", path, times->modtime); | ||
1129 | |||
1130 | int rc, open1rc = -1; | ||
1131 | struct filestr_base pathstr; | ||
1132 | struct path_component_info pathinfo; | ||
1133 | |||
1134 | file_internal_lock_WRITER(); | ||
1135 | |||
1136 | if (!times) | ||
1137 | FILE_ERROR(EINVAL, -1); | ||
1138 | |||
1139 | open1rc = open_stream_internal(path, FF_ANYTYPE | FF_PARENTINFO, | ||
1140 | &pathstr, &pathinfo); | ||
1141 | if (open1rc <= 0) | ||
1142 | { | ||
1143 | DEBUGF("Failed opening path: %d\n", open1rc); | ||
1144 | if (open1rc == 0) | ||
1145 | FILE_ERROR(ENOENT, -2); | ||
1146 | else | ||
1147 | FILE_ERROR(ERRNO, open1rc * 10 - 1); | ||
1148 | } | ||
1149 | |||
1150 | rc = fat_utime(&pathinfo.parentinfo.fatfile, pathstr.fatstr.fatfilep, | ||
1151 | times); | ||
1152 | if (rc < 0) | ||
1153 | { | ||
1154 | DEBUGF("I/O error during utime: %d\n", rc); | ||
1155 | FILE_ERROR(ERRNO, rc * 10 - 2); | ||
1156 | } | ||
1157 | |||
1158 | file_error: | ||
1159 | if (open1rc >= 0) | ||
1160 | close_stream_internal(&pathstr); | ||
1161 | file_internal_unlock_WRITER(); | ||
1162 | return rc; | ||
1163 | } | ||
1126 | 1164 | ||
1127 | /** Extensions **/ | 1165 | /** Extensions **/ |
1128 | 1166 | ||
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index cc9735d0f7..28d4eb1987 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -2276,6 +2276,41 @@ fat_error: | |||
2276 | return rc; | 2276 | return rc; |
2277 | } | 2277 | } |
2278 | 2278 | ||
2279 | int fat_utime(struct fat_file *parent, struct fat_file *file, | ||
2280 | const struct utimbuf *times) | ||
2281 | { | ||
2282 | struct bpb * const fat_bpb = FAT_BPB(parent->volume); | ||
2283 | |||
2284 | if (!fat_bpb) | ||
2285 | return -1; | ||
2286 | |||
2287 | int rc; | ||
2288 | |||
2289 | struct fat_filestr parentstr; | ||
2290 | fat_filestr_init(&parentstr, parent); | ||
2291 | |||
2292 | dc_lock_cache(); | ||
2293 | |||
2294 | union raw_dirent *ent = cache_direntry(fat_bpb, &parentstr, file->e.entry); | ||
2295 | if (!ent) | ||
2296 | FAT_ERROR(-2); | ||
2297 | |||
2298 | uint16_t date; | ||
2299 | uint16_t time; | ||
2300 | dostime_localtime(times->modtime, &date, &time); | ||
2301 | |||
2302 | ent->wrttime = htole16(time); | ||
2303 | ent->wrtdate = htole16(date); | ||
2304 | ent->lstaccdate = htole16(date); | ||
2305 | |||
2306 | dc_dirty_buf(ent); | ||
2307 | |||
2308 | rc = 0; | ||
2309 | fat_error: | ||
2310 | dc_unlock_cache(); | ||
2311 | cache_commit(fat_bpb); | ||
2312 | return rc; | ||
2313 | } | ||
2279 | 2314 | ||
2280 | /** File stream functions **/ | 2315 | /** File stream functions **/ |
2281 | 2316 | ||
diff --git a/firmware/export/fat.h b/firmware/export/fat.h index 27c2a161f6..b83ceeec0d 100644 --- a/firmware/export/fat.h +++ b/firmware/export/fat.h | |||
@@ -140,6 +140,8 @@ enum fat_remove_op /* what should fat_remove(), remove? */ | |||
140 | int fat_remove(struct fat_file *file, enum fat_remove_op what); | 140 | int fat_remove(struct fat_file *file, enum fat_remove_op what); |
141 | int fat_rename(struct fat_file *parent, struct fat_file *file, | 141 | int fat_rename(struct fat_file *parent, struct fat_file *file, |
142 | const unsigned char *newname); | 142 | const unsigned char *newname); |
143 | int fat_utime(struct fat_file *parent, struct fat_file *file, | ||
144 | const struct utimbuf *utimes); | ||
143 | 145 | ||
144 | /** File stream functions **/ | 146 | /** File stream functions **/ |
145 | int fat_closewrite(struct fat_filestr *filestr, uint32_t size, | 147 | int fat_closewrite(struct fat_filestr *filestr, uint32_t size, |
diff --git a/firmware/include/file.h b/firmware/include/file.h index 040f48dfc5..f17f14f98e 100644 --- a/firmware/include/file.h +++ b/firmware/include/file.h | |||
@@ -85,6 +85,9 @@ int fdprintf(int fildes, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3); | |||
85 | #ifndef rename | 85 | #ifndef rename |
86 | #define rename FS_PREFIX(rename) | 86 | #define rename FS_PREFIX(rename) |
87 | #endif | 87 | #endif |
88 | #ifndef utime | ||
89 | #define utime FS_PREFIX(utime) | ||
90 | #endif | ||
88 | #ifndef filesize | 91 | #ifndef filesize |
89 | #define filesize FS_PREFIX(filesize) | 92 | #define filesize FS_PREFIX(filesize) |
90 | #endif | 93 | #endif |
diff --git a/firmware/include/filesystem-native.h b/firmware/include/filesystem-native.h index 640e179890..800e7bb23b 100644 --- a/firmware/include/filesystem-native.h +++ b/firmware/include/filesystem-native.h | |||
@@ -43,6 +43,8 @@ | |||
43 | #define __OPEN_MODE_ARG | 43 | #define __OPEN_MODE_ARG |
44 | #define __CREAT_MODE_ARG | 44 | #define __CREAT_MODE_ARG |
45 | 45 | ||
46 | #include <time.h> | ||
47 | |||
46 | int open(const char *name, int oflag); | 48 | int open(const char *name, int oflag); |
47 | int creat(const char *name); | 49 | int creat(const char *name); |
48 | int close(int fildes); | 50 | int close(int fildes); |
@@ -53,6 +55,7 @@ ssize_t read(int fildes, void *buf, size_t nbyte); | |||
53 | ssize_t write(int fildes, const void *buf, size_t nbyte); | 55 | ssize_t write(int fildes, const void *buf, size_t nbyte); |
54 | int remove(const char *path); | 56 | int remove(const char *path); |
55 | int rename(const char *old, const char *new); | 57 | int rename(const char *old, const char *new); |
58 | int utime(const char *path, const struct utimbuf* times); | ||
56 | off_t filesize(int fildes); | 59 | off_t filesize(int fildes); |
57 | int fsamefile(int fildes1, int fildes2); | 60 | int fsamefile(int fildes1, int fildes2); |
58 | int relate(const char *path1, const char *path2); | 61 | int relate(const char *path1, const char *path2); |
diff --git a/firmware/libc/include/time.h b/firmware/libc/include/time.h index 4796b8b083..217b454321 100644 --- a/firmware/libc/include/time.h +++ b/firmware/libc/include/time.h | |||
@@ -28,6 +28,12 @@ struct tm | |||
28 | #if !defined(_TIME_T_DEFINED) && !defined(_TIME_T_DECLARED) | 28 | #if !defined(_TIME_T_DEFINED) && !defined(_TIME_T_DECLARED) |
29 | typedef long time_t; | 29 | typedef long time_t; |
30 | 30 | ||
31 | struct utimbuf | ||
32 | { | ||
33 | time_t actime; | ||
34 | time_t modtime; | ||
35 | }; | ||
36 | |||
31 | /* this define below is used by the mingw headers to prevent duplicate | 37 | /* this define below is used by the mingw headers to prevent duplicate |
32 | typedefs */ | 38 | typedefs */ |
33 | #define _TIME_T_DEFINED | 39 | #define _TIME_T_DEFINED |