summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Buren <braewoods+rb@braewoods.net>2021-07-07 21:06:31 +0000
committerSolomon Peachy <pizza@shaftnet.org>2021-07-08 13:15:30 +0000
commitc174d3a544b92be55bc0d09443522386363129f5 (patch)
treec0462544de28dff56285a55ff2824daee06c0f34
parente6ee3dd17cf040cf38c8751c99edaec67f7a5ab5 (diff)
downloadrockbox-c174d3a544b92be55bc0d09443522386363129f5.tar.gz
rockbox-c174d3a544b92be55bc0d09443522386363129f5.zip
file/fat: add utime function
This emulates the traditional utime function from UNIX clones to allow for manual updates of the modification timestamp on files and directories. This should only prove useful for non-native targets as those usually have a libc version of utime. Change-Id: Iea8a1d328e78b92c400d3354ee80689c7cf53af8
-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