Closing directory after a complete traversal.

Adding tests for that.
This commit is contained in:
uid20013
2005-08-16 00:11:15 +00:00
parent 865d2453ff
commit e224c98838
2 changed files with 64 additions and 50 deletions

View File

@@ -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 <errno.h>
@@ -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);

View File

@@ -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!"