aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lfs.c57
-rw-r--r--tests/test.lua57
2 files changed, 64 insertions, 50 deletions
diff --git a/src/lfs.c b/src/lfs.c
index 234194d..b2e04f6 100644
--- a/src/lfs.c
+++ b/src/lfs.c
@@ -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
59typedef struct dir_data { 58typedef 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*/
275static int dir_iter (lua_State *L) { 278static 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*/
312static int dir_close (lua_State *L) { 321static 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*/
330static int dir_iter_factory (lua_State *L) { 341static 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"
9function attrdir (path) 9function 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")
32assert (lfs.currentdir() == current, "error trying to change directories") 32assert (lfs.currentdir() == current, "error trying to change directories")
33assert (lfs.chdir ("this couldn't be an actual directory") == nil, "could change to a non-existent directory") 33assert (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
35local tmpdir = tmp..sep.."lfs_tmp_dir" 35local tmpdir = tmp.."/lfs_tmp_dir"
36assert (lfs.mkdir (tmpdir), "could not make a new directory") 36assert (lfs.mkdir (tmpdir), "could not make a new directory")
37-- create a new file 37local attrib, errmsg = lfs.attributes (tmpdir)
38local tmpfile = tmpdir..sep.."lfs_tmp_file"
39assert (io.open(tmpfile, "w"), "could not make a new file")
40local attrib, errmsg = lfs.attributes (tmpfile)
41if not attrib then 38if 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)
43else
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)
59end 40end
60assert (os.remove (tmpfile), "could not remove file") 41-- Change access time
61assert (lfs.rmdir (tmpdir), "could not remove new directory") 42assert (lfs.touch (tmpdir, 11))
62assert (lfs.mkdir (tmpdir..sep.."lfs_tmp_dir") == false, "could create a directory inside a non-existent one") 43local new_att = assert (lfs.attributes (tmpdir))
63-- 44assert (new_att.access == 11, "could not set access time")
45assert (new_att.modification == 11, "could not set modification time")
46-- Change access and modification time
47assert (lfs.touch (tmpdir, 33, 22))
48local new_att = assert (lfs.attributes (tmpdir))
49assert (new_att.access == 33, "could not set access time")
50assert (new_att.modification == 22, "could not set modification time")
51-- Restore access time to current value
52assert (lfs.touch (tmpdir))
53new_att = assert (lfs.attributes (tmpdir))
54assert (new_att.access == attrib.access)
55assert (new_att.modification == attrib.modification)
56-- Remove new directory
57assert (os.remove (tmpdir), "could not remove new directory")
58assert (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
64assert (lfs.attributes ("this couldn't be an actual file") == nil, "could get attributes of a non-existent file") 60assert (lfs.attributes ("this couldn't be an actual file") == nil, "could get attributes of a non-existent file")
65assert (type(lfs.attributes (upper)) == "table", "couldn't get attributes of upper directory") 61assert (type(lfs.attributes (upper)) == "table", "couldn't get attributes of upper directory")
62-- Stressing directory iterator
63count = 0
64for i = 1, 4000 do
65 for file in lfs.dir (tmp) do
66 count = count + 1
67 end
68end
66print"Ok!" 69print"Ok!"