diff options
| author | uid20013 <uid20013> | 2005-08-16 00:11:15 +0000 |
|---|---|---|
| committer | uid20013 <uid20013> | 2005-08-16 00:11:15 +0000 |
| commit | e224c98838fd37372eb9ca592f30e3b888d1cc3a (patch) | |
| tree | 5b54c6fc4b9d34b9538e66484a9b4ce04a6b8bdd /src | |
| parent | 865d2453ff6b3a87a2551b2b398ebbb5d580531a (diff) | |
| download | luafilesystem-e224c98838fd37372eb9ca592f30e3b888d1cc3a.tar.gz luafilesystem-e224c98838fd37372eb9ca592f30e3b888d1cc3a.tar.bz2 luafilesystem-e224c98838fd37372eb9ca592f30e3b888d1cc3a.zip | |
Closing directory after a complete traversal.
Adding tests for that.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lfs.c | 57 |
1 files changed, 34 insertions, 23 deletions
| @@ -11,7 +11,7 @@ | |||
| 11 | ** lfs.touch (filepath [, atime [, mtime]]) | 11 | ** lfs.touch (filepath [, atime [, mtime]]) |
| 12 | ** lfs.unlock (fh) | 12 | ** lfs.unlock (fh) |
| 13 | ** | 13 | ** |
| 14 | ** $Id: lfs.c,v 1.24 2005/06/21 11:46:13 tomas Exp $ | 14 | ** $Id: lfs.c,v 1.25 2005/08/16 00:11:15 uid20013 Exp $ |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <errno.h> | 17 | #include <errno.h> |
| @@ -55,12 +55,15 @@ | |||
| 55 | 55 | ||
| 56 | #define DIR_METATABLE "directory metatable" | 56 | #define DIR_METATABLE "directory metatable" |
| 57 | #define MAX_DIR_LENGTH 1023 | 57 | #define MAX_DIR_LENGTH 1023 |
| 58 | #ifdef _WIN32 | ||
| 59 | typedef struct dir_data { | 58 | typedef struct dir_data { |
| 59 | int closed; | ||
| 60 | #ifdef _WIN32 | ||
| 60 | long hFile; | 61 | long hFile; |
| 61 | char pattern[MAX_DIR_LENGTH+1]; | 62 | char pattern[MAX_DIR_LENGTH+1]; |
| 62 | } dir_data; | 63 | #else |
| 64 | DIR *dir; | ||
| 63 | #endif | 65 | #endif |
| 66 | } dir_data; | ||
| 64 | 67 | ||
| 65 | 68 | ||
| 66 | /* | 69 | /* |
| @@ -273,8 +276,9 @@ static int remove_dir (lua_State *L) { | |||
| 273 | ** Directory iterator | 276 | ** Directory iterator |
| 274 | */ | 277 | */ |
| 275 | static int dir_iter (lua_State *L) { | 278 | static int dir_iter (lua_State *L) { |
| 276 | #ifdef _WIN32 | ||
| 277 | dir_data *d = (dir_data *)lua_touserdata (L, lua_upvalueindex (1)); | 279 | dir_data *d = (dir_data *)lua_touserdata (L, lua_upvalueindex (1)); |
| 280 | luaL_argcheck (L, !d->closed, 1, "closed directory"); | ||
| 281 | #ifdef _WIN32 | ||
| 278 | struct _finddata_t c_file; | 282 | struct _finddata_t c_file; |
| 279 | if (d->hFile == 0L) { /* first entry */ | 283 | if (d->hFile == 0L) { /* first entry */ |
| 280 | if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { | 284 | if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { |
| @@ -286,22 +290,27 @@ static int dir_iter (lua_State *L) { | |||
| 286 | return 1; | 290 | return 1; |
| 287 | } | 291 | } |
| 288 | } else { /* next entry */ | 292 | } else { /* next entry */ |
| 289 | if (_findnext (d->hFile, &c_file) == -1L) | 293 | if (_findnext (d->hFile, &c_file) == -1L) { |
| 294 | /* no more entries => close directory */ | ||
| 295 | _findclose (d->hFile); | ||
| 296 | d->closed = 1; | ||
| 290 | return 0; | 297 | return 0; |
| 291 | else { | 298 | } else { |
| 292 | lua_pushstring (L, c_file.name); | 299 | lua_pushstring (L, c_file.name); |
| 293 | return 1; | 300 | return 1; |
| 294 | } | 301 | } |
| 295 | } | 302 | } |
| 296 | #else | 303 | #else |
| 297 | DIR *d = *(DIR **) lua_touserdata (L, lua_upvalueindex (1)); | ||
| 298 | struct dirent *entry; | 304 | struct dirent *entry; |
| 299 | if ((entry = readdir (d)) != NULL) { | 305 | if ((entry = readdir (d->dir)) != NULL) { |
| 300 | lua_pushstring (L, entry->d_name); | 306 | lua_pushstring (L, entry->d_name); |
| 301 | return 1; | 307 | return 1; |
| 302 | } | 308 | } else { |
| 303 | else | 309 | /* no more entries => close directory */ |
| 310 | closedir (d->dir); | ||
| 311 | d->closed = 1; | ||
| 304 | return 0; | 312 | return 0; |
| 313 | } | ||
| 305 | #endif | 314 | #endif |
| 306 | } | 315 | } |
| 307 | 316 | ||
| @@ -310,15 +319,17 @@ static int dir_iter (lua_State *L) { | |||
| 310 | ** Closes directory iterators | 319 | ** Closes directory iterators |
| 311 | */ | 320 | */ |
| 312 | static int dir_close (lua_State *L) { | 321 | static int dir_close (lua_State *L) { |
| 313 | #ifdef _WIN32 | ||
| 314 | dir_data *d = (dir_data *)lua_touserdata (L, 1); | 322 | dir_data *d = (dir_data *)lua_touserdata (L, 1); |
| 315 | if (d->hFile) { | 323 | #ifdef _WIN32 |
| 324 | if (!d->closed && d->hFile) { | ||
| 316 | _findclose (d->hFile); | 325 | _findclose (d->hFile); |
| 326 | d->closed = 1; | ||
| 317 | } | 327 | } |
| 318 | #else | 328 | #else |
| 319 | DIR *d = *(DIR **)lua_touserdata (L, 1); | 329 | if (!d->closed && d->dir) { |
| 320 | if (d) | 330 | closedir (d->dir); |
| 321 | closedir (d); | 331 | d->closed = 1; |
| 332 | } | ||
| 322 | #endif | 333 | #endif |
| 323 | return 0; | 334 | return 0; |
| 324 | } | 335 | } |
| @@ -329,21 +340,21 @@ static int dir_close (lua_State *L) { | |||
| 329 | */ | 340 | */ |
| 330 | static int dir_iter_factory (lua_State *L) { | 341 | static int dir_iter_factory (lua_State *L) { |
| 331 | const char *path = luaL_checkstring (L, 1); | 342 | const char *path = luaL_checkstring (L, 1); |
| 343 | dir_data *d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); | ||
| 344 | d->closed = 0; | ||
| 332 | #ifdef _WIN32 | 345 | #ifdef _WIN32 |
| 333 | dir_data *dir = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); | 346 | d->hFile = 0L; |
| 334 | dir->hFile = 0L; | 347 | luaL_getmetatable (L, DIR_METATABLE); |
| 348 | lua_setmetatable (L, -2); | ||
| 335 | if (strlen(path) > MAX_DIR_LENGTH) | 349 | if (strlen(path) > MAX_DIR_LENGTH) |
| 336 | luaL_error (L, "path too long: %s", path); | 350 | luaL_error (L, "path too long: %s", path); |
| 337 | else | 351 | else |
| 338 | sprintf (dir->pattern, "%s/*", path); | 352 | sprintf (d->pattern, "%s/*", path); |
| 339 | luaL_getmetatable (L, DIR_METATABLE); | ||
| 340 | lua_setmetatable (L, -2); | ||
| 341 | #else | 353 | #else |
| 342 | DIR **d = (DIR **) lua_newuserdata (L, sizeof(DIR *)); | ||
| 343 | luaL_getmetatable (L, DIR_METATABLE); | 354 | luaL_getmetatable (L, DIR_METATABLE); |
| 344 | lua_setmetatable (L, -2); | 355 | lua_setmetatable (L, -2); |
| 345 | *d = opendir (path); | 356 | d->dir = opendir (path); |
| 346 | if (*d == NULL) | 357 | if (d->dir == NULL) |
| 347 | luaL_error (L, "cannot open %s: %s", path, strerror (errno)); | 358 | luaL_error (L, "cannot open %s: %s", path, strerror (errno)); |
| 348 | #endif | 359 | #endif |
| 349 | lua_pushcclosure (L, dir_iter, 1); | 360 | lua_pushcclosure (L, dir_iter, 1); |
