diff options
-rw-r--r-- | src/lfs.c | 47 |
1 files changed, 14 insertions, 33 deletions
@@ -17,7 +17,7 @@ | |||
17 | ** lfs.touch (filepath [, atime [, mtime]]) | 17 | ** lfs.touch (filepath [, atime [, mtime]]) |
18 | ** lfs.unlock (fh) | 18 | ** lfs.unlock (fh) |
19 | ** | 19 | ** |
20 | ** $Id: lfs.c,v 1.60 2009/06/03 20:49:18 mascarenhas Exp $ | 20 | ** $Id: lfs.c,v 1.61 2009/07/04 02:10:16 mascarenhas Exp $ |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #ifndef _WIN32 | 23 | #ifndef _WIN32 |
@@ -247,55 +247,36 @@ static int lfs_unlock_dir(lua_State *L) { | |||
247 | } | 247 | } |
248 | #else | 248 | #else |
249 | typedef struct lfs_Lock { | 249 | typedef struct lfs_Lock { |
250 | int fd; | ||
251 | char *ln; | 250 | char *ln; |
252 | } lfs_Lock; | 251 | } lfs_Lock; |
253 | static int lfs_lock_dir(lua_State *L) { | 252 | static int lfs_lock_dir(lua_State *L) { |
254 | struct stat statbuf; | ||
255 | lfs_Lock *lock; | 253 | lfs_Lock *lock; |
256 | size_t pathl; int fd; | 254 | size_t pathl; |
257 | char *tmpln, *ln; | 255 | char *ln; |
258 | const char *template = "/lockfile.XXXXXX"; | ||
259 | const char *lockfile = "/lockfile.lfs"; | 256 | const char *lockfile = "/lockfile.lfs"; |
260 | const char *path = luaL_checklstring(L, 1, &pathl); | 257 | const char *path = luaL_checklstring(L, 1, &pathl); |
261 | time_t expires = (time_t)luaL_optint(L, 2, INT_MAX); | 258 | lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); |
262 | tmpln = (char*)malloc(pathl + strlen(template) + 1); | ||
263 | if(!tmpln) { lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; } | ||
264 | strcpy(tmpln, path); strcat(tmpln, template); | ||
265 | fd = mkstemp(tmpln); | ||
266 | if(fd == -1) { | ||
267 | free(tmpln); lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; | ||
268 | } | ||
269 | ln = (char*)malloc(pathl + strlen(lockfile) + 1); | 259 | ln = (char*)malloc(pathl + strlen(lockfile) + 1); |
270 | if(!ln) { | 260 | if(!ln) { |
271 | unlink(tmpln); free(tmpln); close(fd); lua_pushnil(L); | 261 | lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; |
272 | lua_pushstring(L, strerror(errno)); return 2; | ||
273 | } | 262 | } |
274 | strcpy(ln, path); strcat(ln, lockfile); | 263 | strcpy(ln, path); strcat(ln, lockfile); |
275 | while(symlink(tmpln, ln) == -1) { | 264 | if(symlink("lock", ln) == -1) { |
276 | if(errno == EEXIST) { | 265 | free(ln); lua_pushnil(L); |
277 | if(lstat(ln, &statbuf) == -1) goto fail; | 266 | lua_pushstring(L, strerror(errno)); return 2; |
278 | if(time(NULL) - statbuf.st_mtimespec.tv_sec > expires) { | ||
279 | unlink(ln); | ||
280 | continue; | ||
281 | } | ||
282 | } | ||
283 | fail: | ||
284 | unlink(tmpln); free(tmpln); free(ln); close(fd); | ||
285 | lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2; | ||
286 | } | 267 | } |
287 | unlink(tmpln); free(tmpln); | 268 | lock->ln = ln; |
288 | lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); | ||
289 | lock->fd = fd; lock->ln = ln; | ||
290 | luaL_getmetatable (L, LOCK_METATABLE); | 269 | luaL_getmetatable (L, LOCK_METATABLE); |
291 | lua_setmetatable (L, -2); | 270 | lua_setmetatable (L, -2); |
292 | return 1; | 271 | return 1; |
293 | } | 272 | } |
294 | static int lfs_unlock_dir(lua_State *L) { | 273 | static int lfs_unlock_dir(lua_State *L) { |
295 | lfs_Lock *lock = luaL_checkudata(L, 1, LOCK_METATABLE); | 274 | lfs_Lock *lock = luaL_checkudata(L, 1, LOCK_METATABLE); |
296 | unlink(lock->ln); | 275 | if(lock->ln) { |
297 | close(lock->fd); | 276 | unlink(lock->ln); |
298 | free(lock->ln); | 277 | free(lock->ln); |
278 | lock->ln = NULL; | ||
279 | } | ||
299 | return 0; | 280 | return 0; |
300 | } | 281 | } |
301 | #endif | 282 | #endif |