diff options
-rw-r--r-- | src/lfs.c | 57 | ||||
-rw-r--r-- | tests/test.lua | 57 |
2 files changed, 64 insertions, 50 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); |
diff --git a/tests/test.lua b/tests/test.lua index d0018cd..07436f9 100644 --- a/tests/test.lua +++ b/tests/test.lua | |||
@@ -9,7 +9,7 @@ require"lfs" | |||
9 | function attrdir (path) | 9 | function attrdir (path) |
10 | for file in lfs.dir(path) do | 10 | for file in lfs.dir(path) do |
11 | if file ~= "." and file ~= ".." then | 11 | if file ~= "." and file ~= ".." then |
12 | local f = path..sep..file | 12 | local f = path..'/'..file |
13 | print ("\t=> "..f.." <=") | 13 | print ("\t=> "..f.." <=") |
14 | local attr = lfs.attributes (f) | 14 | local attr = lfs.attributes (f) |
15 | assert (type(attr) == "table") | 15 | assert (type(attr) == "table") |
@@ -32,35 +32,38 @@ assert (lfs.chdir (reldir), "could not change back to current directory") | |||
32 | assert (lfs.currentdir() == current, "error trying to change directories") | 32 | assert (lfs.currentdir() == current, "error trying to change directories") |
33 | assert (lfs.chdir ("this couldn't be an actual directory") == nil, "could change to a non-existent directory") | 33 | assert (lfs.chdir ("this couldn't be an actual directory") == nil, "could change to a non-existent directory") |
34 | -- Changing creating and removing directories | 34 | -- Changing creating and removing directories |
35 | local tmpdir = tmp..sep.."lfs_tmp_dir" | 35 | local tmpdir = tmp.."/lfs_tmp_dir" |
36 | assert (lfs.mkdir (tmpdir), "could not make a new directory") | 36 | assert (lfs.mkdir (tmpdir), "could not make a new directory") |
37 | -- create a new file | 37 | local attrib, errmsg = lfs.attributes (tmpdir) |
38 | local tmpfile = tmpdir..sep.."lfs_tmp_file" | ||
39 | assert (io.open(tmpfile, "w"), "could not make a new file") | ||
40 | local attrib, errmsg = lfs.attributes (tmpfile) | ||
41 | if not attrib then | 38 | if not attrib then |
42 | error ("could not get attributes of file `"..tmpfile.."':\n"..errmsg) | 39 | error ("could not get attributes of file `"..tmpdir.."':\n"..errmsg) |
43 | else | ||
44 | -- Change access time | ||
45 | assert (lfs.touch (tmpfile, 11)) | ||
46 | local new_att = assert (lfs.attributes (tmpfile)) | ||
47 | assert (new_att.access == 11, string.format("could not set access time: %s", tostring(new_att.access))) | ||
48 | assert (new_att.modification == 11, "could not set modification time") | ||
49 | -- Change access and modification time | ||
50 | assert (lfs.touch (tmpfile, 33, 22)) | ||
51 | local new_att = assert (lfs.attributes (tmpfile)) | ||
52 | assert (new_att.access == 33, "could not set access time") | ||
53 | assert (new_att.modification == 22, "could not set modification time") | ||
54 | -- Restore access time to current value | ||
55 | assert (lfs.touch (tmpfile)) | ||
56 | new_att = assert (lfs.attributes (tmpfile)) | ||
57 | assert (new_att.access == attrib.access) | ||
58 | assert (new_att.modification == attrib.modification) | ||
59 | end | 40 | end |
60 | assert (os.remove (tmpfile), "could not remove file") | 41 | -- Change access time |
61 | assert (lfs.rmdir (tmpdir), "could not remove new directory") | 42 | assert (lfs.touch (tmpdir, 11)) |
62 | assert (lfs.mkdir (tmpdir..sep.."lfs_tmp_dir") == false, "could create a directory inside a non-existent one") | 43 | local new_att = assert (lfs.attributes (tmpdir)) |
63 | -- | 44 | assert (new_att.access == 11, "could not set access time") |
45 | assert (new_att.modification == 11, "could not set modification time") | ||
46 | -- Change access and modification time | ||
47 | assert (lfs.touch (tmpdir, 33, 22)) | ||
48 | local new_att = assert (lfs.attributes (tmpdir)) | ||
49 | assert (new_att.access == 33, "could not set access time") | ||
50 | assert (new_att.modification == 22, "could not set modification time") | ||
51 | -- Restore access time to current value | ||
52 | assert (lfs.touch (tmpdir)) | ||
53 | new_att = assert (lfs.attributes (tmpdir)) | ||
54 | assert (new_att.access == attrib.access) | ||
55 | assert (new_att.modification == attrib.modification) | ||
56 | -- Remove new directory | ||
57 | assert (os.remove (tmpdir), "could not remove new directory") | ||
58 | assert (lfs.mkdir (tmpdir.."/lfs_tmp_dir") == false, "could create a directory inside a non-existent one") | ||
59 | -- Trying to get attributes of a non-existent file | ||
64 | assert (lfs.attributes ("this couldn't be an actual file") == nil, "could get attributes of a non-existent file") | 60 | assert (lfs.attributes ("this couldn't be an actual file") == nil, "could get attributes of a non-existent file") |
65 | assert (type(lfs.attributes (upper)) == "table", "couldn't get attributes of upper directory") | 61 | assert (type(lfs.attributes (upper)) == "table", "couldn't get attributes of upper directory") |
62 | -- Stressing directory iterator | ||
63 | count = 0 | ||
64 | for i = 1, 4000 do | ||
65 | for file in lfs.dir (tmp) do | ||
66 | count = count + 1 | ||
67 | end | ||
68 | end | ||
66 | print"Ok!" | 69 | print"Ok!" |