summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/common/file.c38
-rw-r--r--firmware/drivers/fat.c35
-rw-r--r--firmware/export/fat.h2
-rw-r--r--firmware/include/file.h3
-rw-r--r--firmware/include/filesystem-native.h3
-rw-r--r--firmware/libc/include/time.h6
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
1126int 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
1158file_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
2279int 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;
2309fat_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? */
140int fat_remove(struct fat_file *file, enum fat_remove_op what); 140int fat_remove(struct fat_file *file, enum fat_remove_op what);
141int fat_rename(struct fat_file *parent, struct fat_file *file, 141int fat_rename(struct fat_file *parent, struct fat_file *file,
142 const unsigned char *newname); 142 const unsigned char *newname);
143int 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 **/
145int fat_closewrite(struct fat_filestr *filestr, uint32_t size, 147int 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
46int open(const char *name, int oflag); 48int open(const char *name, int oflag);
47int creat(const char *name); 49int creat(const char *name);
48int close(int fildes); 50int close(int fildes);
@@ -53,6 +55,7 @@ ssize_t read(int fildes, void *buf, size_t nbyte);
53ssize_t write(int fildes, const void *buf, size_t nbyte); 55ssize_t write(int fildes, const void *buf, size_t nbyte);
54int remove(const char *path); 56int remove(const char *path);
55int rename(const char *old, const char *new); 57int rename(const char *old, const char *new);
58int utime(const char *path, const struct utimbuf* times);
56off_t filesize(int fildes); 59off_t filesize(int fildes);
57int fsamefile(int fildes1, int fildes2); 60int fsamefile(int fildes1, int fildes2);
58int relate(const char *path1, const char *path2); 61int 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)
29typedef long time_t; 29typedef long time_t;
30 30
31struct 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