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 /src | |
| parent | 53d2acc5173e20a843d26d88ffa4767b01868e02 (diff) | |
| download | luafilesystem-94700f7c18c90455f9b627b69f93c94f773a972e.tar.gz luafilesystem-94700f7c18c90455f9b627b69f93c94f773a972e.tar.bz2 luafilesystem-94700f7c18c90455f9b627b69f93c94f773a972e.zip | |
win32: obtain symlink attributes
Diffstat (limited to 'src')
| -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 | /* |
