diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2021-01-23 15:13:48 -0300 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2021-01-23 15:49:05 -0300 |
commit | d68db4ca79b31c923442fcc5013e92473309f8c2 (patch) | |
tree | 47e50f5e3e593db23e8944b7cfbfb90839b1e2a2 | |
parent | 6adf412a256181e07b4859c3703fb4dc6023007e (diff) | |
download | luafilesystem-high-precision-times.tar.gz luafilesystem-high-precision-times.tar.bz2 luafilesystem-high-precision-times.zip |
accept high-precision timestamps in lfs.touchhigh-precision-times
-rw-r--r-- | src/lfs.c | 41 | ||||
-rw-r--r-- | tests/test.lua | 15 |
2 files changed, 50 insertions, 6 deletions
@@ -172,6 +172,15 @@ typedef struct dir_data { | |||
172 | 172 | ||
173 | #endif | 173 | #endif |
174 | 174 | ||
175 | #if _POSIX_VERSION >= 200809L | ||
176 | #define UTIME_FUNC(dirp, name, utb) utimensat(dirp ? dirfd(dirp) : 0, name, utb, 0) | ||
177 | #define UTIME_STRUCT struct timespec | ||
178 | #else | ||
179 | #define UTIME_FUNC(dirp, name, utb) utime(name, utb) | ||
180 | #define UTIME_STRUCT struct utimbuf | ||
181 | #endif | ||
182 | |||
183 | |||
175 | #ifdef _WIN32 | 184 | #ifdef _WIN32 |
176 | #define lfs_mkdir _mkdir | 185 | #define lfs_mkdir _mkdir |
177 | #else | 186 | #else |
@@ -820,17 +829,39 @@ static const char *mode2string(mode_t mode) | |||
820 | static int file_utime(lua_State * L) | 829 | static int file_utime(lua_State * L) |
821 | { | 830 | { |
822 | const char *file = luaL_checkstring(L, 1); | 831 | const char *file = luaL_checkstring(L, 1); |
823 | struct utimbuf utb, *buf; | 832 | UTIME_STRUCT utb[2]; |
833 | UTIME_STRUCT *buf; | ||
834 | #ifndef _WIN32 | ||
835 | DIR* dirp = NULL; | ||
836 | #endif | ||
824 | 837 | ||
825 | if (lua_gettop(L) == 1) /* set to current date/time */ | 838 | if (lua_gettop(L) == 1) /* set to current date/time */ |
826 | buf = NULL; | 839 | buf = NULL; |
827 | else { | 840 | else { |
828 | utb.actime = (time_t) luaL_optnumber(L, 2, 0); | 841 | #if _POSIX_VERSION >= 200809L |
829 | utb.modtime = (time_t) luaL_optinteger(L, 3, utb.actime); | 842 | lua_Number acctime = luaL_optnumber(L, 2, 0); |
830 | buf = &utb; | 843 | lua_Number modtime = luaL_optnumber(L, 3, acctime); |
844 | utb[0].tv_sec = acctime; | ||
845 | utb[0].tv_nsec = (acctime - utb[0].tv_sec) * 1000000000; | ||
846 | utb[1].tv_sec = modtime; | ||
847 | utb[1].tv_nsec = (modtime - utb[1].tv_sec) * 1000000000; | ||
848 | if (file[0] != '/') { | ||
849 | dirp = opendir("."); | ||
850 | } | ||
851 | #else | ||
852 | utb[0].actime = (time_t) luaL_optnumber(L, 2, 0); | ||
853 | utb[0].modtime = (time_t) luaL_optnumber(L, 3, utb[0].actime); | ||
854 | #endif | ||
855 | buf = utb; | ||
831 | } | 856 | } |
832 | 857 | ||
833 | return pushresult(L, utime(file, buf), NULL); | 858 | int res = UTIME_FUNC(dirp, file, buf); |
859 | #ifndef _WIN32 | ||
860 | if (dirp) { | ||
861 | closedir(dirp); | ||
862 | } | ||
863 | #endif | ||
864 | return pushresult(L, res, NULL); | ||
834 | } | 865 | } |
835 | 866 | ||
836 | 867 | ||
diff --git a/tests/test.lua b/tests/test.lua index 3ace810..5d00e44 100644 --- a/tests/test.lua +++ b/tests/test.lua | |||
@@ -79,6 +79,19 @@ assert (new_att.modification == testdate, "could not set modification time") | |||
79 | io.write(".") | 79 | io.write(".") |
80 | io.flush() | 80 | io.flush() |
81 | 81 | ||
82 | -- High-precision attributes | ||
83 | local testdate_hi = os.time({ year = 2021, day = 1, month = 23, hour=0}) + 0.5555 | ||
84 | assert (lfs.touch (tmpfile, testdate_hi)) | ||
85 | local new_att_hi = assert (lfs.attributes (tmpfile)) | ||
86 | if new_att_hi.modification ~= testdate_hi then | ||
87 | io.write("\n") | ||
88 | io.write("warning: no support for high-precision timestamps\n") | ||
89 | io.flush() | ||
90 | end | ||
91 | |||
92 | io.write(".") | ||
93 | io.flush() | ||
94 | |||
82 | -- Change access and modification time | 95 | -- Change access and modification time |
83 | local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0}) | 96 | local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0}) |
84 | local testdate2 = os.time({ year = 2007, day = 11, month = 2, hour=0}) | 97 | local testdate2 = os.time({ year = 2007, day = 11, month = 2, hour=0}) |
@@ -194,7 +207,7 @@ io.write(".") | |||
194 | io.flush() | 207 | io.flush() |
195 | 208 | ||
196 | -- Stressing directory iterator | 209 | -- Stressing directory iterator |
197 | count = 0 | 210 | local count = 0 |
198 | for i = 1, 4000 do | 211 | for i = 1, 4000 do |
199 | for file in lfs.dir (tmp) do | 212 | for file in lfs.dir (tmp) do |
200 | count = count + 1 | 213 | count = count + 1 |