aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lfs.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/src/lfs.c b/src/lfs.c
index 45adf4a..de5918f 100644
--- a/src/lfs.c
+++ b/src/lfs.c
@@ -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"
88typedef 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
211typedef struct lfs_Lock {
212 HANDLE fd;
213} lfs_Lock;
214static int lfs_lock_dir(lua_State *L) { 214static 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}
217static int lfs_unlock_dir(lua_State *L) { 238static 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
244typedef struct lfs_Lock {
245 int fd;
246 char *ln;
247} lfs_Lock;
221static int lfs_lock_dir(lua_State *L) { 248static 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: