diff options
| -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 |
