diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2020-04-20 22:51:39 -0300 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2020-04-21 13:45:50 -0300 |
commit | 94700f7c18c90455f9b627b69f93c94f773a972e (patch) | |
tree | aa96c6cdc534cb8fcc55df7a50324a623fe0f8e5 | |
parent | 53d2acc5173e20a843d26d88ffa4767b01868e02 (diff) | |
download | luafilesystem-94700f7c18c90455f9b627b69f93c94f773a972e.tar.gz luafilesystem-94700f7c18c90455f9b627b69f93c94f773a972e.tar.bz2 luafilesystem-94700f7c18c90455f9b627b69f93c94f773a972e.zip |
win32: obtain symlink attributes
-rw-r--r-- | src/lfs.c | 104 |
1 files changed, 78 insertions, 26 deletions
@@ -121,7 +121,6 @@ typedef struct dir_data { | |||
121 | #define lfs_setmode(file, m) (_setmode(_fileno(file), m)) | 121 | #define lfs_setmode(file, m) (_setmode(_fileno(file), m)) |
122 | #define STAT_STRUCT struct _stati64 | 122 | #define STAT_STRUCT struct _stati64 |
123 | #endif | 123 | #endif |
124 | |||
125 | #ifndef _S_IFLNK | 124 | #ifndef _S_IFLNK |
126 | #define _S_IFLNK 0x400 | 125 | #define _S_IFLNK 0x400 |
127 | #endif | 126 | #endif |
@@ -166,6 +165,51 @@ typedef struct dir_data { | |||
166 | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH)) | 165 | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH)) |
167 | #endif | 166 | #endif |
168 | 167 | ||
168 | #ifdef _WIN32 | ||
169 | |||
170 | int lfs_win32_pusherror(lua_State *L) | ||
171 | { | ||
172 | int en = GetLastError(); | ||
173 | lua_pushnil(L); | ||
174 | if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION) | ||
175 | lua_pushstring(L, "File exists"); | ||
176 | else | ||
177 | lua_pushstring(L, strerror(en)); | ||
178 | return 2; | ||
179 | } | ||
180 | |||
181 | #define TICKS_PER_SECOND 10000000 | ||
182 | #define EPOCH_DIFFERENCE 11644473600LL | ||
183 | time_t windowsToUnixTime(FILETIME ft) | ||
184 | { | ||
185 | ULARGE_INTEGER uli; | ||
186 | uli.LowPart = ft.dwLowDateTime; | ||
187 | uli.HighPart = ft.dwHighDateTime; | ||
188 | return (time_t)(uli.QuadPart / TICKS_PER_SECOND - EPOCH_DIFFERENCE); | ||
189 | } | ||
190 | |||
191 | int lfs_win32_lstat(const char *path, STAT_STRUCT *buffer) | ||
192 | { | ||
193 | WIN32_FILE_ATTRIBUTE_DATA win32buffer; | ||
194 | if (GetFileAttributesEx(path, GetFileExInfoStandard, &win32buffer)) { | ||
195 | buffer->st_mode = _S_IFLNK; | ||
196 | buffer->st_dev = 0; | ||
197 | buffer->st_ino = 0; | ||
198 | buffer->st_nlink = 0; | ||
199 | buffer->st_uid = 0; | ||
200 | buffer->st_gid = 0; | ||
201 | buffer->st_rdev = 0; | ||
202 | buffer->st_atime = windowsToUnixTime(win32buffer.ftLastAccessTime); | ||
203 | buffer->st_mtime = windowsToUnixTime(win32buffer.ftLastWriteTime); | ||
204 | buffer->st_ctime = windowsToUnixTime(win32buffer.ftCreationTime); | ||
205 | buffer->st_size = 0; | ||
206 | return 0; | ||
207 | } else { | ||
208 | return 1; | ||
209 | } | ||
210 | } | ||
211 | #endif | ||
212 | |||
169 | /* | 213 | /* |
170 | ** Utility functions | 214 | ** Utility functions |
171 | */ | 215 | */ |
@@ -335,17 +379,12 @@ static int lfs_lock_dir(lua_State *L) { | |||
335 | lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; | 379 | lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; |
336 | } | 380 | } |
337 | strcpy(ln, path); strcat(ln, lockfile); | 381 | strcpy(ln, path); strcat(ln, lockfile); |
338 | if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW, | 382 | fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW, |
339 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) { | 383 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); |
340 | int en = GetLastError(); | ||
341 | free(ln); lua_pushnil(L); | ||
342 | if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION) | ||
343 | lua_pushstring(L, "File exists"); | ||
344 | else | ||
345 | lua_pushstring(L, strerror(en)); | ||
346 | return 2; | ||
347 | } | ||
348 | free(ln); | 384 | free(ln); |
385 | if(fd == INVALID_HANDLE_VALUE) { | ||
386 | return lfs_win32_pusherror(L); | ||
387 | } | ||
349 | lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); | 388 | lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); |
350 | lock->fd = fd; | 389 | lock->fd = fd; |
351 | luaL_getmetatable (L, LOCK_METATABLE); | 390 | luaL_getmetatable (L, LOCK_METATABLE); |
@@ -884,35 +923,48 @@ static int file_info (lua_State *L) { | |||
884 | ** 0 on failure (with stack unchanged, and errno set). | 923 | ** 0 on failure (with stack unchanged, and errno set). |
885 | */ | 924 | */ |
886 | static int push_link_target(lua_State *L) { | 925 | static int push_link_target(lua_State *L) { |
887 | #ifdef _WIN32 | ||
888 | errno = ENOSYS; | ||
889 | return 0; | ||
890 | #else | ||
891 | const char *file = luaL_checkstring(L, 1); | 926 | const char *file = luaL_checkstring(L, 1); |
927 | #ifdef _WIN32 | ||
928 | HANDLE h = CreateFile(file, GENERIC_READ, | ||
929 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | ||
930 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | ||
931 | if (h == INVALID_HANDLE_VALUE) { | ||
932 | return lfs_win32_pusherror(L); | ||
933 | } | ||
934 | #endif | ||
892 | char *target = NULL; | 935 | char *target = NULL; |
893 | int tsize, size = 256; /* size = initial buffer capacity */ | 936 | int tsize, size = 256; /* size = initial buffer capacity */ |
894 | while (1) { | 937 | int ok = 0; |
938 | while (!ok) { | ||
895 | char* target2 = realloc(target, size); | 939 | char* target2 = realloc(target, size); |
896 | if (!target2) { /* failed to allocate */ | 940 | if (!target2) { /* failed to allocate */ |
897 | free(target); | 941 | break; |
898 | return 0; | ||
899 | } | 942 | } |
900 | target = target2; | 943 | target = target2; |
944 | #ifdef _WIN32 | ||
945 | tsize = GetFinalPathNameByHandle(h, target, size, FILE_NAME_OPENED); | ||
946 | #else | ||
901 | tsize = readlink(file, target, size); | 947 | tsize = readlink(file, target, size); |
948 | #endif | ||
902 | if (tsize < 0) { /* a readlink() error occurred */ | 949 | if (tsize < 0) { /* a readlink() error occurred */ |
903 | free(target); | 950 | break; |
904 | return 0; | 951 | } |
952 | if (tsize < size) { | ||
953 | ok = 1; | ||
954 | break; | ||
905 | } | 955 | } |
906 | if (tsize < size) | ||
907 | break; | ||
908 | /* possibly truncated readlink() result, double size and retry */ | 956 | /* possibly truncated readlink() result, double size and retry */ |
909 | size *= 2; | 957 | size *= 2; |
910 | } | 958 | } |
911 | target[tsize] = '\0'; | 959 | if (ok) { |
912 | lua_pushlstring(L, target, tsize); | 960 | target[tsize] = '\0'; |
913 | free(target); | 961 | lua_pushlstring(L, target, tsize); |
914 | return 1; | 962 | } |
963 | #ifdef _WIN32 | ||
964 | CloseHandle(h); | ||
915 | #endif | 965 | #endif |
966 | free(target); | ||
967 | return ok; | ||
916 | } | 968 | } |
917 | 969 | ||
918 | /* | 970 | /* |