From d71c63cdb776f7d25313f8fcd14f07512ba1f83e Mon Sep 17 00:00:00 2001
From: Fabio Mascarenhas
Date: Mon, 1 Oct 2012 11:11:48 -0300
Subject: luafilesystem 1.6.0
---
README | 6 +
doc/us/index.html | 9 +-
rockspecs/luafilesystem-1.6.0-1.rockspec | 27 ++
src/lfs.c | 660 +++++++++++++++----------------
tests/test.lua | 81 +++-
5 files changed, 431 insertions(+), 352 deletions(-)
create mode 100644 rockspecs/luafilesystem-1.6.0-1.rockspec
diff --git a/README b/README
index 0103efa..6610243 100644
--- a/README
+++ b/README
@@ -22,6 +22,12 @@ Please check the documentation at doc/us/ for more information.
History
-------
+Version 1.6.0 [26/Sep/2012]
+ * getcwd fix for Android
+ * support for Lua 5.2
+ * add lfs.link
+ * other bug fixes
+
Version 1.5.0 [20/Oct/2009]
* added explicit next and close methods to second return value of lfs.dir (the directory object), for explicit iteration or explicit closing.
* added directory locking via lfs.lock_dir function (see the manual).
diff --git a/doc/us/index.html b/doc/us/index.html
index 9798404..6d7072b 100644
--- a/doc/us/index.html
+++ b/doc/us/index.html
@@ -71,7 +71,8 @@ the underlying directory structure and file attributes.
Status
-Current version is 1.5.0. It was developed for Lua 5.1.
+Current version is 1.6.0. It was developed for Lua 5.1 but also
+ works with Lua 5.2.
Download
@@ -82,6 +83,12 @@ page.
History
+ - Version 1.6.0 [26/Sep/2012]
+
getcwd fix for Android
+ support for Lua 5.2
+ add lfs.link
+ other bug fixes
+
Version 1.5.0 [20/Oct/2009]
Added explicit next and close methods to second return value of lfs.dir
(the directory object), for explicit iteration or explicit closing.
diff --git a/rockspecs/luafilesystem-1.6.0-1.rockspec b/rockspecs/luafilesystem-1.6.0-1.rockspec
new file mode 100644
index 0000000..82d349c
--- /dev/null
+++ b/rockspecs/luafilesystem-1.6.0-1.rockspec
@@ -0,0 +1,27 @@
+package = "LuaFileSystem"
+
+version = "1.6.0-1"
+
+source = {
+ url = "https://github.com/downloads/keplerproject/luafilesystem/luafilesystem-1.6.0.tar.gz",
+}
+
+description = {
+ summary = "File System Library for the Lua Programming Language",
+ detailed = [[
+ LuaFileSystem is a Lua library developed to complement the set of
+ functions related to file systems offered by the standard Lua
+ distribution. LuaFileSystem offers a portable way to access the
+ underlying directory structure and file attributes.
+ ]]
+}
+
+dependencies = {
+ "lua >= 5.1"
+}
+
+build = {
+ type = "builtin",
+ modules = { lfs = "src/lfs.c" },
+ copy_directories = { "doc", "tests" }
+}
diff --git a/src/lfs.c b/src/lfs.c
index faba9bb..87323b3 100644
--- a/src/lfs.c
+++ b/src/lfs.c
@@ -67,21 +67,21 @@
#if (LUA_VERSION_NUM == 502)
#undef luaL_register
#define luaL_register(L,n,f) \
- { if ((n) == NULL) luaL_setfuncs(L,f,0); else luaL_newlib(L,f); }
+ { if ((n) == NULL) luaL_setfuncs(L,f,0); else luaL_newlib(L,f); }
#endif
/* Define 'strerror' for systems that do not implement it */
#ifdef NO_STRERROR
-#define strerror(_) "System unable to describe the error"
+#define strerror(_) "System unable to describe the error"
#endif
/* Define 'getcwd' for systems that do not implement it */
#ifdef NO_GETCWD
-#define getcwd(p,s) NULL
-#define getcwd_error "Function 'getcwd' not provided by system"
+#define getcwd(p,s) NULL
+#define getcwd_error "Function 'getcwd' not provided by system"
#else
-#define getcwd_error strerror(errno)
+#define getcwd_error strerror(errno)
#ifdef _WIN32
#define LFS_MAXPATHLEN MAX_PATH // MAX_PATH seems to be 260. Seems kind of small. Is there a better one?
#else
@@ -92,12 +92,12 @@
#define DIR_METATABLE "directory metatable"
typedef struct dir_data {
- int closed;
+ int closed;
#ifdef _WIN32
- long hFile;
- char pattern[MAX_PATH+1];
+ long hFile;
+ char pattern[MAX_PATH+1];
#else
- DIR *dir;
+ DIR *dir;
#endif
} dir_data;
@@ -127,21 +127,21 @@ typedef struct dir_data {
*/
static int pusherror(lua_State *L, const char *info)
{
- lua_pushnil(L);
- if (info==NULL)
- lua_pushstring(L, strerror(errno));
- else
- lua_pushfstring(L, "%s: %s", info, strerror(errno));
- lua_pushinteger(L, errno);
- return 3;
+ lua_pushnil(L);
+ if (info==NULL)
+ lua_pushstring(L, strerror(errno));
+ else
+ lua_pushfstring(L, "%s: %s", info, strerror(errno));
+ lua_pushinteger(L, errno);
+ return 3;
}
static int pushresult(lua_State *L, int i, const char *info)
{
- if (i==-1)
- return pusherror(L, info);
- lua_pushinteger(L, i);
- return 1;
+ if (i==-1)
+ return pusherror(L, info);
+ lua_pushinteger(L, i);
+ return 1;
}
@@ -149,16 +149,16 @@ static int pushresult(lua_State *L, int i, const char *info)
** This function changes the working (current) directory
*/
static int change_dir (lua_State *L) {
- const char *path = luaL_checkstring(L, 1);
- if (chdir(path)) {
- lua_pushnil (L);
- lua_pushfstring (L,"Unable to change working directory to '%s'\n%s\n",
- path, chdir_error);
- return 2;
- } else {
- lua_pushboolean (L, 1);
- return 1;
- }
+ const char *path = luaL_checkstring(L, 1);
+ if (chdir(path)) {
+ lua_pushnil (L);
+ lua_pushfstring (L,"Unable to change working directory to '%s'\n%s\n",
+ path, chdir_error);
+ return 2;
+ } else {
+ lua_pushboolean (L, 1);
+ return 1;
+ }
}
/*
@@ -169,7 +169,7 @@ static int change_dir (lua_State *L) {
static int get_dir (lua_State *L) {
char *path;
// Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead.
- char buf[LFS_MAXPATHLEN];
+ char buf[LFS_MAXPATHLEN];
if ((path = getcwd(buf, LFS_MAXPATHLEN)) == NULL) {
lua_pushnil(L);
lua_pushstring(L, getcwd_error);
@@ -185,15 +185,15 @@ static int get_dir (lua_State *L) {
** Check if the given element on the stack is a file and returns it.
*/
static FILE *check_file (lua_State *L, int idx, const char *funcname) {
- FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*");
- if (fh == NULL) {
- luaL_error (L, "%s: not a file", funcname);
- return 0;
- } else if (*fh == NULL) {
- luaL_error (L, "%s: closed file", funcname);
- return 0;
- } else
- return *fh;
+ FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*");
+ if (fh == NULL) {
+ luaL_error (L, "%s: not a file", funcname);
+ return 0;
+ } else if (*fh == NULL) {
+ luaL_error (L, "%s: closed file", funcname);
+ return 0;
+ } else
+ return *fh;
}
@@ -201,50 +201,50 @@ static FILE *check_file (lua_State *L, int idx, const char *funcname) {
**
*/
static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long start, long len, const char *funcname) {
- int code;
+ int code;
#ifdef _WIN32
- /* lkmode valid values are:
- LK_LOCK Locks the specified bytes. If the bytes cannot be locked, the program immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, the constant returns an error.
- LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.
- LK_NBRLCK Same as _LK_NBLCK.
- LK_RLCK Same as _LK_LOCK.
- LK_UNLCK Unlocks the specified bytes, which must have been previously locked.
-
- Regions should be locked only briefly and should be unlocked before closing a file or exiting the program.
-
- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp
- */
- int lkmode;
- switch (*mode) {
- case 'r': lkmode = LK_NBLCK; break;
- case 'w': lkmode = LK_NBLCK; break;
- case 'u': lkmode = LK_UNLCK; break;
- default : return luaL_error (L, "%s: invalid mode", funcname);
- }
- if (!len) {
- fseek (fh, 0L, SEEK_END);
- len = ftell (fh);
- }
- fseek (fh, start, SEEK_SET);
+ /* lkmode valid values are:
+ LK_LOCK Locks the specified bytes. If the bytes cannot be locked, the program immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, the constant returns an error.
+ LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.
+ LK_NBRLCK Same as _LK_NBLCK.
+ LK_RLCK Same as _LK_LOCK.
+ LK_UNLCK Unlocks the specified bytes, which must have been previously locked.
+
+ Regions should be locked only briefly and should be unlocked before closing a file or exiting the program.
+
+ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp
+ */
+ int lkmode;
+ switch (*mode) {
+ case 'r': lkmode = LK_NBLCK; break;
+ case 'w': lkmode = LK_NBLCK; break;
+ case 'u': lkmode = LK_UNLCK; break;
+ default : return luaL_error (L, "%s: invalid mode", funcname);
+ }
+ if (!len) {
+ fseek (fh, 0L, SEEK_END);
+ len = ftell (fh);
+ }
+ fseek (fh, start, SEEK_SET);
#ifdef __BORLANDC__
- code = locking (fileno(fh), lkmode, len);
+ code = locking (fileno(fh), lkmode, len);
#else
- code = _locking (fileno(fh), lkmode, len);
+ code = _locking (fileno(fh), lkmode, len);
#endif
#else
- struct flock f;
- switch (*mode) {
- case 'w': f.l_type = F_WRLCK; break;
- case 'r': f.l_type = F_RDLCK; break;
- case 'u': f.l_type = F_UNLCK; break;
- default : return luaL_error (L, "%s: invalid mode", funcname);
- }
- f.l_whence = SEEK_SET;
- f.l_start = (off_t)start;
- f.l_len = (off_t)len;
- code = fcntl (fileno(fh), F_SETLK, &f);
+ struct flock f;
+ switch (*mode) {
+ case 'w': f.l_type = F_WRLCK; break;
+ case 'r': f.l_type = F_RDLCK; break;
+ case 'u': f.l_type = F_UNLCK; break;
+ default : return luaL_error (L, "%s: invalid mode", funcname);
+ }
+ f.l_whence = SEEK_SET;
+ f.l_start = (off_t)start;
+ f.l_len = (off_t)len;
+ code = fcntl (fileno(fh), F_SETLK, &f);
#endif
- return (code != -1);
+ return (code != -1);
}
#ifdef _WIN32
@@ -258,19 +258,19 @@ static int lfs_lock_dir(lua_State *L) {
const char *lockfile = "/lockfile.lfs";
const char *path = luaL_checklstring(L, 1, &pathl);
ln = (char*)malloc(pathl + strlen(lockfile) + 1);
- if(!ln) {
+ if(!ln) {
lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2;
}
strcpy(ln, path); strcat(ln, lockfile);
- if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) {
- int en = GetLastError();
- free(ln); lua_pushnil(L);
- if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION)
- lua_pushstring(L, "File exists");
- else
- lua_pushstring(L, strerror(en));
- return 2;
+ if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) {
+ int en = GetLastError();
+ free(ln); lua_pushnil(L);
+ if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION)
+ lua_pushstring(L, "File exists");
+ else
+ lua_pushstring(L, strerror(en));
+ return 2;
}
free(ln);
lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock));
@@ -296,12 +296,12 @@ static int lfs_lock_dir(lua_State *L) {
const char *path = luaL_checklstring(L, 1, &pathl);
lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock));
ln = (char*)malloc(pathl + strlen(lockfile) + 1);
- if(!ln) {
+ if(!ln) {
lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2;
}
strcpy(ln, path); strcat(ln, lockfile);
if(symlink("lock", ln) == -1) {
- free(ln); lua_pushnil(L);
+ free(ln); lua_pushnil(L);
lua_pushstring(L, strerror(errno)); return 2;
}
lock->ln = ln;
@@ -358,18 +358,18 @@ static int lfs_f_setmode(lua_State *L) {
** @param #4 Number with length (optional).
*/
static int file_lock (lua_State *L) {
- FILE *fh = check_file (L, 1, "lock");
- const char *mode = luaL_checkstring (L, 2);
- const long start = luaL_optlong (L, 3, 0);
- long len = luaL_optlong (L, 4, 0);
- if (_file_lock (L, fh, mode, start, len, "lock")) {
- lua_pushboolean (L, 1);
- return 1;
- } else {
- lua_pushnil (L);
- lua_pushfstring (L, "%s", strerror(errno));
- return 2;
- }
+ FILE *fh = check_file (L, 1, "lock");
+ const char *mode = luaL_checkstring (L, 2);
+ const long start = luaL_optlong (L, 3, 0);
+ long len = luaL_optlong (L, 4, 0);
+ if (_file_lock (L, fh, mode, start, len, "lock")) {
+ lua_pushboolean (L, 1);
+ return 1;
+ } else {
+ lua_pushnil (L);
+ lua_pushfstring (L, "%s", strerror(errno));
+ return 2;
+ }
}
@@ -380,17 +380,17 @@ static int file_lock (lua_State *L) {
** @param #3 Number with length (optional).
*/
static int file_unlock (lua_State *L) {
- FILE *fh = check_file (L, 1, "unlock");
- const long start = luaL_optlong (L, 2, 0);
- long len = luaL_optlong (L, 3, 0);
- if (_file_lock (L, fh, "u", start, len, "unlock")) {
- lua_pushboolean (L, 1);
- return 1;
- } else {
- lua_pushnil (L);
- lua_pushfstring (L, "%s", strerror(errno));
- return 2;
- }
+ FILE *fh = check_file (L, 1, "unlock");
+ const long start = luaL_optlong (L, 2, 0);
+ long len = luaL_optlong (L, 3, 0);
+ if (_file_lock (L, fh, "u", start, len, "unlock")) {
+ lua_pushboolean (L, 1);
+ return 1;
+ } else {
+ lua_pushnil (L);
+ lua_pushfstring (L, "%s", strerror(errno));
+ return 2;
+ }
}
@@ -403,10 +403,10 @@ static int file_unlock (lua_State *L) {
static int make_link(lua_State *L)
{
#ifndef _WIN32
- const char *oldpath = luaL_checkstring(L, 1);
- const char *newpath = luaL_checkstring(L, 2);
- return pushresult(L,
- (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL);
+ const char *oldpath = luaL_checkstring(L, 1);
+ const char *newpath = luaL_checkstring(L, 2);
+ return pushresult(L,
+ (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL);
#else
pusherror(L, "make_link is not supported on Windows");
#endif
@@ -418,21 +418,21 @@ static int make_link(lua_State *L)
** @param #1 Directory path.
*/
static int make_dir (lua_State *L) {
- const char *path = luaL_checkstring (L, 1);
- int fail;
+ const char *path = luaL_checkstring (L, 1);
+ int fail;
#ifdef _WIN32
- fail = _mkdir (path);
+ fail = _mkdir (path);
#else
- fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
- S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH );
+ fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
+ S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH );
#endif
- if (fail) {
- lua_pushnil (L);
+ if (fail) {
+ lua_pushnil (L);
lua_pushfstring (L, "%s", strerror(errno));
- return 2;
- }
- lua_pushboolean (L, 1);
- return 1;
+ return 2;
+ }
+ lua_pushboolean (L, 1);
+ return 1;
}
/*
@@ -440,18 +440,18 @@ static int make_dir (lua_State *L) {
** @param #1 Directory path.
*/
static int remove_dir (lua_State *L) {
- const char *path = luaL_checkstring (L, 1);
- int fail;
+ const char *path = luaL_checkstring (L, 1);
+ int fail;
- fail = rmdir (path);
+ fail = rmdir (path);
- if (fail) {
- lua_pushnil (L);
- lua_pushfstring (L, "%s", strerror(errno));
- return 2;
- }
- lua_pushboolean (L, 1);
- return 1;
+ if (fail) {
+ lua_pushnil (L);
+ lua_pushfstring (L, "%s", strerror(errno));
+ return 2;
+ }
+ lua_pushboolean (L, 1);
+ return 1;
}
/*
@@ -459,44 +459,44 @@ static int remove_dir (lua_State *L) {
*/
static int dir_iter (lua_State *L) {
#ifdef _WIN32
- struct _finddata_t c_file;
+ struct _finddata_t c_file;
#else
- struct dirent *entry;
+ struct dirent *entry;
#endif
- dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE);
- luaL_argcheck (L, d->closed == 0, 1, "closed directory");
+ dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE);
+ luaL_argcheck (L, d->closed == 0, 1, "closed directory");
#ifdef _WIN32
- if (d->hFile == 0L) { /* first entry */
- if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) {
- lua_pushnil (L);
- lua_pushstring (L, strerror (errno));
- d->closed = 1;
- return 2;
- } else {
- lua_pushstring (L, c_file.name);
- return 1;
- }
- } else { /* next entry */
- if (_findnext (d->hFile, &c_file) == -1L) {
- /* no more entries => close directory */
- _findclose (d->hFile);
- d->closed = 1;
- return 0;
- } else {
- lua_pushstring (L, c_file.name);
- return 1;
- }
- }
+ if (d->hFile == 0L) { /* first entry */
+ if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) {
+ lua_pushnil (L);
+ lua_pushstring (L, strerror (errno));
+ d->closed = 1;
+ return 2;
+ } else {
+ lua_pushstring (L, c_file.name);
+ return 1;
+ }
+ } else { /* next entry */
+ if (_findnext (d->hFile, &c_file) == -1L) {
+ /* no more entries => close directory */
+ _findclose (d->hFile);
+ d->closed = 1;
+ return 0;
+ } else {
+ lua_pushstring (L, c_file.name);
+ return 1;
+ }
+ }
#else
- if ((entry = readdir (d->dir)) != NULL) {
- lua_pushstring (L, entry->d_name);
- return 1;
- } else {
- /* no more entries => close directory */
- closedir (d->dir);
- d->closed = 1;
- return 0;
- }
+ if ((entry = readdir (d->dir)) != NULL) {
+ lua_pushstring (L, entry->d_name);
+ return 1;
+ } else {
+ /* no more entries => close directory */
+ closedir (d->dir);
+ d->closed = 1;
+ return 0;
+ }
#endif
}
@@ -505,18 +505,18 @@ static int dir_iter (lua_State *L) {
** Closes directory iterators
*/
static int dir_close (lua_State *L) {
- dir_data *d = (dir_data *)lua_touserdata (L, 1);
+ dir_data *d = (dir_data *)lua_touserdata (L, 1);
#ifdef _WIN32
- if (!d->closed && d->hFile) {
- _findclose (d->hFile);
- }
+ if (!d->closed && d->hFile) {
+ _findclose (d->hFile);
+ }
#else
- if (!d->closed && d->dir) {
- closedir (d->dir);
- }
+ if (!d->closed && d->dir) {
+ closedir (d->dir);
+ }
#endif
- d->closed = 1;
- return 0;
+ d->closed = 1;
+ return 0;
}
@@ -524,25 +524,25 @@ static int dir_close (lua_State *L) {
** Factory of directory iterators
*/
static int dir_iter_factory (lua_State *L) {
- const char *path = luaL_checkstring (L, 1);
- dir_data *d;
- lua_pushcfunction (L, dir_iter);
- d = (dir_data *) lua_newuserdata (L, sizeof(dir_data));
- luaL_getmetatable (L, DIR_METATABLE);
- lua_setmetatable (L, -2);
- d->closed = 0;
+ const char *path = luaL_checkstring (L, 1);
+ dir_data *d;
+ lua_pushcfunction (L, dir_iter);
+ d = (dir_data *) lua_newuserdata (L, sizeof(dir_data));
+ luaL_getmetatable (L, DIR_METATABLE);
+ lua_setmetatable (L, -2);
+ d->closed = 0;
#ifdef _WIN32
- d->hFile = 0L;
- if (strlen(path) > MAX_PATH-2)
- luaL_error (L, "path too long: %s", path);
- else
- sprintf (d->pattern, "%s/*", path);
+ d->hFile = 0L;
+ if (strlen(path) > MAX_PATH-2)
+ luaL_error (L, "path too long: %s", path);
+ else
+ sprintf (d->pattern, "%s/*", path);
#else
- d->dir = opendir (path);
- if (d->dir == NULL)
+ d->dir = opendir (path);
+ if (d->dir == NULL)
luaL_error (L, "cannot open %s: %s", path, strerror (errno));
#endif
- return 2;
+ return 2;
}
@@ -550,38 +550,38 @@ static int dir_iter_factory (lua_State *L) {
** Creates directory metatable.
*/
static int dir_create_meta (lua_State *L) {
- luaL_newmetatable (L, DIR_METATABLE);
+ luaL_newmetatable (L, DIR_METATABLE);
/* Method table */
- lua_newtable(L);
- lua_pushcfunction (L, dir_iter);
- lua_setfield(L, -2, "next");
- lua_pushcfunction (L, dir_close);
- lua_setfield(L, -2, "close");
+ lua_newtable(L);
+ lua_pushcfunction (L, dir_iter);
+ lua_setfield(L, -2, "next");
+ lua_pushcfunction (L, dir_close);
+ lua_setfield(L, -2, "close");
/* Metamethods */
- lua_setfield(L, -2, "__index");
- lua_pushcfunction (L, dir_close);
- lua_setfield (L, -2, "__gc");
- return 1;
+ lua_setfield(L, -2, "__index");
+ lua_pushcfunction (L, dir_close);
+ lua_setfield (L, -2, "__gc");
+ return 1;
}
/*
** Creates lock metatable.
*/
static int lock_create_meta (lua_State *L) {
- luaL_newmetatable (L, LOCK_METATABLE);
+ luaL_newmetatable (L, LOCK_METATABLE);
/* Method table */
- lua_newtable(L);
- lua_pushcfunction(L, lfs_unlock_dir);
- lua_setfield(L, -2, "free");
+ lua_newtable(L);
+ lua_pushcfunction(L, lfs_unlock_dir);
+ lua_setfield(L, -2, "free");
/* Metamethods */
- lua_setfield(L, -2, "__index");
- lua_pushcfunction(L, lfs_unlock_dir);
- lua_setfield(L, -2, "__gc");
- return 1;
+ lua_setfield(L, -2, "__index");
+ lua_pushcfunction(L, lfs_unlock_dir);
+ lua_setfield(L, -2, "__gc");
+ return 1;
}
@@ -621,17 +621,17 @@ static const char *mode2string (mode_t mode) {
else if ( S_ISDIR(mode) )
return "directory";
else if ( S_ISLNK(mode) )
- return "link";
+ return "link";
else if ( S_ISSOCK(mode) )
return "socket";
else if ( S_ISFIFO(mode) )
- return "named pipe";
+ return "named pipe";
else if ( S_ISCHR(mode) )
- return "char device";
+ return "char device";
else if ( S_ISBLK(mode) )
- return "block device";
+ return "block device";
else
- return "other";
+ return "other";
}
@@ -639,78 +639,78 @@ static const char *mode2string (mode_t mode) {
** Set access time and modification values for file
*/
static int file_utime (lua_State *L) {
- const char *file = luaL_checkstring (L, 1);
- struct utimbuf utb, *buf;
-
- if (lua_gettop (L) == 1) /* set to current date/time */
- buf = NULL;
- else {
- utb.actime = (time_t)luaL_optnumber (L, 2, 0);
- utb.modtime = (time_t)luaL_optnumber (L, 3, utb.actime);
- buf = &utb;
- }
- if (utime (file, buf)) {
- lua_pushnil (L);
- lua_pushfstring (L, "%s", strerror (errno));
- return 2;
- }
- lua_pushboolean (L, 1);
- return 1;
+ const char *file = luaL_checkstring (L, 1);
+ struct utimbuf utb, *buf;
+
+ if (lua_gettop (L) == 1) /* set to current date/time */
+ buf = NULL;
+ else {
+ utb.actime = (time_t)luaL_optnumber (L, 2, 0);
+ utb.modtime = (time_t)luaL_optnumber (L, 3, utb.actime);
+ buf = &utb;
+ }
+ if (utime (file, buf)) {
+ lua_pushnil (L);
+ lua_pushfstring (L, "%s", strerror (errno));
+ return 2;
+ }
+ lua_pushboolean (L, 1);
+ return 1;
}
/* inode protection mode */
static void push_st_mode (lua_State *L, STAT_STRUCT *info) {
- lua_pushstring (L, mode2string (info->st_mode));
+ lua_pushstring (L, mode2string (info->st_mode));
}
/* device inode resides on */
static void push_st_dev (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_dev);
+ lua_pushnumber (L, (lua_Number)info->st_dev);
}
/* inode's number */
static void push_st_ino (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_ino);
+ lua_pushnumber (L, (lua_Number)info->st_ino);
}
/* number of hard links to the file */
static void push_st_nlink (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_nlink);
+ lua_pushnumber (L, (lua_Number)info->st_nlink);
}
/* user-id of owner */
static void push_st_uid (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_uid);
+ lua_pushnumber (L, (lua_Number)info->st_uid);
}
/* group-id of owner */
static void push_st_gid (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_gid);
+ lua_pushnumber (L, (lua_Number)info->st_gid);
}
/* device type, for special file inode */
static void push_st_rdev (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_rdev);
+ lua_pushnumber (L, (lua_Number)info->st_rdev);
}
/* time of last access */
static void push_st_atime (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, info->st_atime);
+ lua_pushnumber (L, info->st_atime);
}
/* time of last data modification */
static void push_st_mtime (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, info->st_mtime);
+ lua_pushnumber (L, info->st_mtime);
}
/* time of last file status change */
static void push_st_ctime (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, info->st_ctime);
+ lua_pushnumber (L, info->st_ctime);
}
/* file size, in bytes */
static void push_st_size (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_size);
+ lua_pushnumber (L, (lua_Number)info->st_size);
}
#ifndef _WIN32
/* blocks allocated for file */
static void push_st_blocks (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_blocks);
+ lua_pushnumber (L, (lua_Number)info->st_blocks);
}
/* optimal file system I/O blocksize */
static void push_st_blksize (lua_State *L, STAT_STRUCT *info) {
- lua_pushnumber (L, (lua_Number)info->st_blksize);
+ lua_pushnumber (L, (lua_Number)info->st_blksize);
}
#endif
static void push_invalid (lua_State *L, STAT_STRUCT *info) {
@@ -763,68 +763,68 @@ static void push_st_perm (lua_State *L, STAT_STRUCT *info) {
typedef void (*_push_function) (lua_State *L, STAT_STRUCT *info);
struct _stat_members {
- const char *name;
- _push_function push;
+ const char *name;
+ _push_function push;
};
struct _stat_members members[] = {
- { "mode", push_st_mode },
- { "dev", push_st_dev },
- { "ino", push_st_ino },
- { "nlink", push_st_nlink },
- { "uid", push_st_uid },
- { "gid", push_st_gid },
- { "rdev", push_st_rdev },
- { "access", push_st_atime },
- { "modification", push_st_mtime },
- { "change", push_st_ctime },
- { "size", push_st_size },
- { "permissions", push_st_perm },
+ { "mode", push_st_mode },
+ { "dev", push_st_dev },
+ { "ino", push_st_ino },
+ { "nlink", push_st_nlink },
+ { "uid", push_st_uid },
+ { "gid", push_st_gid },
+ { "rdev", push_st_rdev },
+ { "access", push_st_atime },
+ { "modification", push_st_mtime },
+ { "change", push_st_ctime },
+ { "size", push_st_size },
+ { "permissions", push_st_perm },
#ifndef _WIN32
- { "blocks", push_st_blocks },
- { "blksize", push_st_blksize },
+ { "blocks", push_st_blocks },
+ { "blksize", push_st_blksize },
#endif
- { NULL, push_invalid }
+ { NULL, push_invalid }
};
/*
** Get file or symbolic link information
*/
static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
- int i;
- STAT_STRUCT info;
- const char *file = luaL_checkstring (L, 1);
-
- if (st(file, &info)) {
- lua_pushnil (L);
- lua_pushfstring (L, "cannot obtain information from file `%s'", file);
- return 2;
- }
- if (lua_isstring (L, 2)) {
- int v;
- const char *member = lua_tostring (L, 2);
- if (strcmp (member, "mode") == 0) v = 0;
+ int i;
+ STAT_STRUCT info;
+ const char *file = luaL_checkstring (L, 1);
+
+ if (st(file, &info)) {
+ lua_pushnil (L);
+ lua_pushfstring (L, "cannot obtain information from file `%s'", file);
+ return 2;
+ }
+ if (lua_isstring (L, 2)) {
+ int v;
+ const char *member = lua_tostring (L, 2);
+ if (strcmp (member, "mode") == 0) v = 0;
#ifndef _WIN32
- else if (strcmp (member, "blocks") == 0) v = 11;
- else if (strcmp (member, "blksize") == 0) v = 12;
+ else if (strcmp (member, "blocks") == 0) v = 11;
+ else if (strcmp (member, "blksize") == 0) v = 12;
#endif
- else /* look for member */
- for (v = 1; members[v].name; v++)
- if (*members[v].name == *member)
- break;
- /* push member value and return */
- members[v].push (L, &info);
- return 1;
- } else if (!lua_istable (L, 2))
- /* creates a table if none is given */
- lua_newtable (L);
- /* stores all members in table on top of the stack */
- for (i = 0; members[i].name; i++) {
- lua_pushstring (L, members[i].name);
- members[i].push (L, &info);
- lua_rawset (L, -3);
- }
- return 1;
+ else /* look for member */
+ for (v = 1; members[v].name; v++)
+ if (*members[v].name == *member)
+ break;
+ /* push member value and return */
+ members[v].push (L, &info);
+ return 1;
+ } else if (!lua_istable (L, 2))
+ /* creates a table if none is given */
+ lua_newtable (L);
+ /* stores all members in table on top of the stack */
+ for (i = 0; members[i].name; i++) {
+ lua_pushstring (L, members[i].name);
+ members[i].push (L, &info);
+ lua_rawset (L, -3);
+ }
+ return 1;
}
@@ -832,7 +832,7 @@ static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
** Get file information using stat.
*/
static int file_info (lua_State *L) {
- return _file_info_ (L, STAT_FUNC);
+ return _file_info_ (L, STAT_FUNC);
}
@@ -840,7 +840,7 @@ static int file_info (lua_State *L) {
** Get symbolic link information using lstat.
*/
static int link_info (lua_State *L) {
- return _file_info_ (L, LSTAT_FUNC);
+ return _file_info_ (L, LSTAT_FUNC);
}
@@ -848,48 +848,48 @@ static int link_info (lua_State *L) {
** Assumes the table is on top of the stack.
*/
static void set_info (lua_State *L) {
- lua_pushliteral (L, "_COPYRIGHT");
- lua_pushliteral (L, "Copyright (C) 2003-2009 Kepler Project");
- lua_settable (L, -3);
- lua_pushliteral (L, "_DESCRIPTION");
- lua_pushliteral (L, "LuaFileSystem is a Lua library developed to complement the set of functions related to file systems offered by the standard Lua distribution");
- lua_settable (L, -3);
- lua_pushliteral (L, "_VERSION");
- lua_pushliteral (L, "LuaFileSystem 1.5.0");
- lua_settable (L, -3);
+ lua_pushliteral (L, "_COPYRIGHT");
+ lua_pushliteral (L, "Copyright (C) 2003-2012 Kepler Project");
+ lua_settable (L, -3);
+ lua_pushliteral (L, "_DESCRIPTION");
+ lua_pushliteral (L, "LuaFileSystem is a Lua library developed to complement the set of functions related to file systems offered by the standard Lua distribution");
+ lua_settable (L, -3);
+ lua_pushliteral (L, "_VERSION");
+ lua_pushliteral (L, "LuaFileSystem 1.6.0");
+ lua_settable (L, -3);
}
static const struct luaL_Reg fslib[] = {
- {"attributes", file_info},
- {"chdir", change_dir},
- {"currentdir", get_dir},
- {"dir", dir_iter_factory},
+ {"attributes", file_info},
+ {"chdir", change_dir},
+ {"currentdir", get_dir},
+ {"dir", dir_iter_factory},
{"link", make_link},
- {"lock", file_lock},
- {"mkdir", make_dir},
- {"rmdir", remove_dir},
- {"symlinkattributes", link_info},
- {"setmode", lfs_f_setmode},
- {"touch", file_utime},
- {"unlock", file_unlock},
- {"lock_dir", lfs_lock_dir},
- {NULL, NULL},
+ {"lock", file_lock},
+ {"mkdir", make_dir},
+ {"rmdir", remove_dir},
+ {"symlinkattributes", link_info},
+ {"setmode", lfs_f_setmode},
+ {"touch", file_utime},
+ {"unlock", file_unlock},
+ {"lock_dir", lfs_lock_dir},
+ {NULL, NULL},
};
#if LUA_VERSION_NUM > 501
static void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l)
{
- luaL_newlib (L, l);
- lua_pushvalue (L, -1);
- lua_setglobal (L, libname);
+ luaL_newlib (L, l);
+ lua_pushvalue (L, -1);
+ lua_setglobal (L, libname);
}
#endif
int luaopen_lfs (lua_State *L) {
- dir_create_meta (L);
- lock_create_meta (L);
- luaL_register (L, "lfs", fslib);
- set_info (L);
- return 1;
+ dir_create_meta (L);
+ lock_create_meta (L);
+ luaL_register (L, "lfs", fslib);
+ set_info (L);
+ return 1;
}
diff --git a/tests/test.lua b/tests/test.lua
index 20948df..4990aec 100644
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -7,22 +7,25 @@ local upper = ".."
local lfs = require"lfs"
print (lfs._VERSION)
+io.write(".")
+io.flush()
+
function attrdir (path)
- for file in lfs.dir(path) do
- if file ~= "." and file ~= ".." then
- local f = path..sep..file
- print ("\t=> "..f.." <=")
- local attr = lfs.attributes (f)
- assert (type(attr) == "table")
- if attr.mode == "directory" then
- attrdir (f)
- else
- for name, value in pairs(attr) do
- print (name, value)
- end
- end
- end
- end
+ for file in lfs.dir(path) do
+ if file ~= "." and file ~= ".." then
+ local f = path..sep..file
+ print ("\t=> "..f.." <=")
+ local attr = lfs.attributes (f)
+ assert (type(attr) == "table")
+ if attr.mode == "directory" then
+ attrdir (f)
+ else
+ for name, value in pairs(attr) do
+ print (name, value)
+ end
+ end
+ end
+ end
end
-- Checking changing directories
@@ -33,6 +36,9 @@ 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")
+io.write(".")
+io.flush()
+
-- Changing creating and removing directories
local tmpdir = current..sep.."lfs_tmp_dir"
local tmpfile = tmpdir..sep.."tmp_file"
@@ -40,19 +46,25 @@ local tmpfile = tmpdir..sep.."tmp_file"
-- that may have resulted from an interrupted test execution and remove it
if lfs.chdir (tmpdir) then
assert (lfs.chdir (upper), "could not change to upper directory")
- assert (os.remove (tmpfile), "could not remove file from previous test")
+ assert (os.remove (tmpfile), "could not remove file from previous test")
assert (lfs.rmdir (tmpdir), "could not remove directory from previous test")
end
+io.write(".")
+io.flush()
+
-- tries to create a directory
assert (lfs.mkdir (tmpdir), "could not make a new directory")
local attrib, errmsg = lfs.attributes (tmpdir)
if not attrib then
- error ("could not get attributes of file `"..tmpdir.."':\n"..errmsg)
+ error ("could not get attributes of file `"..tmpdir.."':\n"..errmsg)
end
local f = io.open(tmpfile, "w")
f:close()
+io.write(".")
+io.flush()
+
-- Change access time
local testdate = os.time({ year = 2007, day = 10, month = 2, hour=0})
assert (lfs.touch (tmpfile, testdate))
@@ -60,6 +72,9 @@ local new_att = assert (lfs.attributes (tmpfile))
assert (new_att.access == testdate, "could not set access time")
assert (new_att.modification == testdate, "could not set modification time")
+io.write(".")
+io.flush()
+
-- Change access and modification time
local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0})
local testdate2 = os.time({ year = 2007, day = 11, month = 2, hour=0})
@@ -69,6 +84,9 @@ local new_att = assert (lfs.attributes (tmpfile))
assert (new_att.access == testdate2, "could not set access time")
assert (new_att.modification == testdate1, "could not set modification time")
+io.write(".")
+io.flush()
+
-- Checking link (does not work on Windows)
if lfs.link (tmpfile, "_a_link_for_test_", true) then
assert (lfs.attributes"_a_link_for_test_".mode == "file")
@@ -79,6 +97,9 @@ if lfs.link (tmpfile, "_a_link_for_test_", true) then
assert (os.remove"_a_hard_link_for_test_")
end
+io.write(".")
+io.flush()
+
-- Checking text/binary modes (only has an effect in Windows)
local f = io.open(tmpfile, "w")
local result, mode = lfs.setmode(f, "binary")
@@ -86,30 +107,45 @@ assert(result) -- on non-Windows platforms, mode is always returned as "binary"
result, mode = lfs.setmode(f, "text")
assert(result and mode == "binary")
f:close()
-
+
+io.write(".")
+io.flush()
+
-- Restore access time to current value
assert (lfs.touch (tmpfile, attrib.access, attrib.modification))
new_att = assert (lfs.attributes (tmpfile))
assert (new_att.access == attrib.access)
assert (new_att.modification == attrib.modification)
+io.write(".")
+io.flush()
+
-- Remove new file and directory
assert (os.remove (tmpfile), "could not remove new file")
assert (lfs.rmdir (tmpdir), "could not remove new directory")
assert (lfs.mkdir (tmpdir..sep.."lfs_tmp_dir") == nil, "could create a directory inside a non-existent one")
+io.write(".")
+io.flush()
+
-- 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")
+io.write(".")
+io.flush()
+
-- Stressing directory iterator
count = 0
for i = 1, 4000 do
- for file in lfs.dir (tmp) do
- count = count + 1
- end
+ for file in lfs.dir (tmp) do
+ count = count + 1
+ end
end
+io.write(".")
+io.flush()
+
-- Stressing directory iterator, explicit version
count = 0
for i = 1, 4000 do
@@ -122,6 +158,9 @@ for i = 1, 4000 do
assert(not pcall(dir.next, dir))
end
+io.write(".")
+io.flush()
+
-- directory explicit close
local iter, dir = lfs.dir(tmp)
dir:close()
--
cgit v1.2.3-55-g6feb