aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2021-01-23 15:13:48 -0300
committerHisham Muhammad <hisham@gobolinux.org>2021-01-23 15:49:05 -0300
commitd68db4ca79b31c923442fcc5013e92473309f8c2 (patch)
tree47e50f5e3e593db23e8944b7cfbfb90839b1e2a2
parent6adf412a256181e07b4859c3703fb4dc6023007e (diff)
downloadluafilesystem-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.c41
-rw-r--r--tests/test.lua15
2 files changed, 50 insertions, 6 deletions
diff --git a/src/lfs.c b/src/lfs.c
index 1b74a31..2b9d292 100644
--- a/src/lfs.c
+++ b/src/lfs.c
@@ -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)
820static int file_utime(lua_State * L) 829static 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")
79io.write(".") 79io.write(".")
80io.flush() 80io.flush()
81 81
82-- High-precision attributes
83local testdate_hi = os.time({ year = 2021, day = 1, month = 23, hour=0}) + 0.5555
84assert (lfs.touch (tmpfile, testdate_hi))
85local new_att_hi = assert (lfs.attributes (tmpfile))
86if 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()
90end
91
92io.write(".")
93io.flush()
94
82-- Change access and modification time 95-- Change access and modification time
83local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0}) 96local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0})
84local testdate2 = os.time({ year = 2007, day = 11, month = 2, hour=0}) 97local testdate2 = os.time({ year = 2007, day = 11, month = 2, hour=0})
@@ -194,7 +207,7 @@ io.write(".")
194io.flush() 207io.flush()
195 208
196-- Stressing directory iterator 209-- Stressing directory iterator
197count = 0 210local count = 0
198for i = 1, 4000 do 211for 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