diff options
-rw-r--r-- | src/lfs.c | 45 |
1 files changed, 36 insertions, 9 deletions
@@ -16,7 +16,7 @@ | |||
16 | ** lfs.touch (filepath [, atime [, mtime]]) | 16 | ** lfs.touch (filepath [, atime [, mtime]]) |
17 | ** lfs.unlock (fh) | 17 | ** lfs.unlock (fh) |
18 | ** | 18 | ** |
19 | ** $Id: lfs.c,v 1.57 2009/03/25 19:14:17 mascarenhas Exp $ | 19 | ** $Id: lfs.c,v 1.58 2009/04/24 22:11:12 mascarenhas Exp $ |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #ifndef _WIN32 | 22 | #ifndef _WIN32 |
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | #ifdef _WIN32 | 39 | #ifdef _WIN32 |
40 | #include <direct.h> | 40 | #include <direct.h> |
41 | #include <windows.h> | ||
41 | #include <io.h> | 42 | #include <io.h> |
42 | #include <sys/locking.h> | 43 | #include <sys/locking.h> |
43 | #ifdef __BORLANDC__ | 44 | #ifdef __BORLANDC__ |
@@ -85,10 +86,6 @@ typedef struct dir_data { | |||
85 | } dir_data; | 86 | } dir_data; |
86 | 87 | ||
87 | #define LOCK_METATABLE "lock metatable" | 88 | #define LOCK_METATABLE "lock metatable" |
88 | typedef struct lfs_Lock { | ||
89 | int fd; | ||
90 | char *ln; | ||
91 | } lfs_Lock; | ||
92 | 89 | ||
93 | #ifdef _WIN32 | 90 | #ifdef _WIN32 |
94 | #ifdef __BORLANDC__ | 91 | #ifdef __BORLANDC__ |
@@ -211,13 +208,43 @@ static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long star | |||
211 | } | 208 | } |
212 | 209 | ||
213 | #ifdef _WIN32 | 210 | #ifdef _WIN32 |
211 | typedef struct lfs_Lock { | ||
212 | HANDLE fd; | ||
213 | } lfs_Lock; | ||
214 | static int lfs_lock_dir(lua_State *L) { | 214 | static int lfs_lock_dir(lua_State *L) { |
215 | luaL_error(L, "not implemented for Windows"); | 215 | size_t pathl; HANDLE fd; |
216 | lfs_Lock *lock; | ||
217 | char *ln; | ||
218 | const char *lockfile = "/lockfile.lfs"; | ||
219 | const char *path = luaL_checklstring(L, 1, &pathl); | ||
220 | ln = (char*)malloc(pathl + strlen(lockfile) + 1); | ||
221 | if(!ln) { | ||
222 | lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; | ||
223 | } | ||
224 | strcpy(ln, path); strcat(ln, lockfile); | ||
225 | while((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW, | ||
226 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) { | ||
227 | int en = GetLastError(); | ||
228 | if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION) continue; | ||
229 | free(ln); lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; | ||
230 | } | ||
231 | free(ln); | ||
232 | lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); | ||
233 | lock->fd = fd; | ||
234 | luaL_getmetatable (L, LOCK_METATABLE); | ||
235 | lua_setmetatable (L, -2); | ||
236 | return 1; | ||
216 | } | 237 | } |
217 | static int lfs_unlock_dir(lua_State *L) { | 238 | static int lfs_unlock_dir(lua_State *L) { |
218 | luaL_error(L, "not implemented for Windows"); | 239 | lfs_Lock *lock = luaL_checkudata(L, 1, LOCK_METATABLE); |
240 | CloseHandle(lock->fd); | ||
241 | return 0; | ||
219 | } | 242 | } |
220 | #else | 243 | #else |
244 | typedef struct lfs_Lock { | ||
245 | int fd; | ||
246 | char *ln; | ||
247 | } lfs_Lock; | ||
221 | static int lfs_lock_dir(lua_State *L) { | 248 | static int lfs_lock_dir(lua_State *L) { |
222 | struct stat statbuf; | 249 | struct stat statbuf; |
223 | lfs_Lock *lock; | 250 | lfs_Lock *lock; |
@@ -244,8 +271,8 @@ static int lfs_lock_dir(lua_State *L) { | |||
244 | if(errno == EEXIST) { | 271 | if(errno == EEXIST) { |
245 | if(lstat(ln, &statbuf) == -1) goto fail; | 272 | if(lstat(ln, &statbuf) == -1) goto fail; |
246 | if(time(NULL) - statbuf.st_mtimespec.tv_sec > expires) { | 273 | if(time(NULL) - statbuf.st_mtimespec.tv_sec > expires) { |
247 | unlink(ln); | 274 | unlink(ln); |
248 | continue; | 275 | continue; |
249 | } | 276 | } |
250 | } | 277 | } |
251 | fail: | 278 | fail: |