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 @@ ** lfs.touch (filepath [, atime [, mtime]]) ** lfs.unlock (fh) ** -** $Id: lfs.c,v 1.24 2005/06/21 11:46:13 tomas Exp $ +** $Id: lfs.c,v 1.25 2005/08/16 00:11:15 uid20013 Exp $ */ #include @@ -55,12 +55,15 @@ #define DIR_METATABLE "directory metatable" #define MAX_DIR_LENGTH 1023 -#ifdef _WIN32 typedef struct dir_data { + int closed; +#ifdef _WIN32 long hFile; char pattern[MAX_DIR_LENGTH+1]; -} dir_data; +#else + DIR *dir; #endif +} dir_data; /* @@ -273,8 +276,9 @@ static int remove_dir (lua_State *L) { ** Directory iterator */ static int dir_iter (lua_State *L) { -#ifdef _WIN32 dir_data *d = (dir_data *)lua_touserdata (L, lua_upvalueindex (1)); + luaL_argcheck (L, !d->closed, 1, "closed directory"); +#ifdef _WIN32 struct _finddata_t c_file; if (d->hFile == 0L) { /* first entry */ if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { @@ -286,22 +290,27 @@ static int dir_iter (lua_State *L) { return 1; } } else { /* next entry */ - if (_findnext (d->hFile, &c_file) == -1L) + if (_findnext (d->hFile, &c_file) == -1L) { + /* no more entries => close directory */ + _findclose (d->hFile); + d->closed = 1; return 0; - else { + } else { lua_pushstring (L, c_file.name); return 1; } } #else - DIR *d = *(DIR **) lua_touserdata (L, lua_upvalueindex (1)); struct dirent *entry; - if ((entry = readdir (d)) != NULL) { + if ((entry = readdir (d->dir)) != NULL) { lua_pushstring (L, entry->d_name); return 1; - } - else + } else { + /* no more entries => close directory */ + closedir (d->dir); + d->closed = 1; return 0; + } #endif } @@ -310,15 +319,17 @@ static int dir_iter (lua_State *L) { ** Closes directory iterators */ static int dir_close (lua_State *L) { -#ifdef _WIN32 dir_data *d = (dir_data *)lua_touserdata (L, 1); - if (d->hFile) { +#ifdef _WIN32 + if (!d->closed && d->hFile) { _findclose (d->hFile); + d->closed = 1; } #else - DIR *d = *(DIR **)lua_touserdata (L, 1); - if (d) - closedir (d); + if (!d->closed && d->dir) { + closedir (d->dir); + d->closed = 1; + } #endif return 0; } @@ -329,21 +340,21 @@ static int dir_close (lua_State *L) { */ static int dir_iter_factory (lua_State *L) { const char *path = luaL_checkstring (L, 1); + dir_data *d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); + d->closed = 0; #ifdef _WIN32 - dir_data *dir = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); - dir->hFile = 0L; + d->hFile = 0L; + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); if (strlen(path) > MAX_DIR_LENGTH) luaL_error (L, "path too long: %s", path); else - sprintf (dir->pattern, "%s/*", path); - luaL_getmetatable (L, DIR_METATABLE); - lua_setmetatable (L, -2); + sprintf (d->pattern, "%s/*", path); #else - DIR **d = (DIR **) lua_newuserdata (L, sizeof(DIR *)); luaL_getmetatable (L, DIR_METATABLE); lua_setmetatable (L, -2); - *d = opendir (path); - if (*d == NULL) + d->dir = opendir (path); + if (d->dir == NULL) luaL_error (L, "cannot open %s: %s", path, strerror (errno)); #endif 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" function attrdir (path) for file in lfs.dir(path) do if file ~= "." and file ~= ".." then - local f = path..sep..file + local f = path..'/'..file print ("\t=> "..f.." <=") local attr = lfs.attributes (f) assert (type(attr) == "table") @@ -32,35 +32,38 @@ assert (lfs.chdir (reldir), "could not change back to current directory") assert (lfs.currentdir() == current, "error trying to change directories") assert (lfs.chdir ("this couldn't be an actual directory") == nil, "could change to a non-existent directory") -- Changing creating and removing directories -local tmpdir = tmp..sep.."lfs_tmp_dir" +local tmpdir = tmp.."/lfs_tmp_dir" assert (lfs.mkdir (tmpdir), "could not make a new directory") --- create a new file -local tmpfile = tmpdir..sep.."lfs_tmp_file" -assert (io.open(tmpfile, "w"), "could not make a new file") -local attrib, errmsg = lfs.attributes (tmpfile) +local attrib, errmsg = lfs.attributes (tmpdir) if not attrib then - error ("could not get attributes of file `"..tmpfile.."':\n"..errmsg) -else - -- Change access time - assert (lfs.touch (tmpfile, 11)) - local new_att = assert (lfs.attributes (tmpfile)) - assert (new_att.access == 11, string.format("could not set access time: %s", tostring(new_att.access))) - assert (new_att.modification == 11, "could not set modification time") - -- Change access and modification time - assert (lfs.touch (tmpfile, 33, 22)) - local new_att = assert (lfs.attributes (tmpfile)) - assert (new_att.access == 33, "could not set access time") - assert (new_att.modification == 22, "could not set modification time") - -- Restore access time to current value - assert (lfs.touch (tmpfile)) - new_att = assert (lfs.attributes (tmpfile)) - assert (new_att.access == attrib.access) - assert (new_att.modification == attrib.modification) + error ("could not get attributes of file `"..tmpdir.."':\n"..errmsg) end -assert (os.remove (tmpfile), "could not remove file") -assert (lfs.rmdir (tmpdir), "could not remove new directory") -assert (lfs.mkdir (tmpdir..sep.."lfs_tmp_dir") == false, "could create a directory inside a non-existent one") --- +-- Change access time +assert (lfs.touch (tmpdir, 11)) +local new_att = assert (lfs.attributes (tmpdir)) +assert (new_att.access == 11, "could not set access time") +assert (new_att.modification == 11, "could not set modification time") +-- Change access and modification time +assert (lfs.touch (tmpdir, 33, 22)) +local new_att = assert (lfs.attributes (tmpdir)) +assert (new_att.access == 33, "could not set access time") +assert (new_att.modification == 22, "could not set modification time") +-- Restore access time to current value +assert (lfs.touch (tmpdir)) +new_att = assert (lfs.attributes (tmpdir)) +assert (new_att.access == attrib.access) +assert (new_att.modification == attrib.modification) +-- Remove new directory +assert (os.remove (tmpdir), "could not remove new directory") +assert (lfs.mkdir (tmpdir.."/lfs_tmp_dir") == false, "could create a directory inside a non-existent one") +-- Trying to get attributes of a non-existent file assert (lfs.attributes ("this couldn't be an actual file") == nil, "could get attributes of a non-existent file") assert (type(lfs.attributes (upper)) == "table", "couldn't get attributes of upper directory") +-- Stressing directory iterator +count = 0 +for i = 1, 4000 do + for file in lfs.dir (tmp) do + count = count + 1 + end +end print"Ok!"