mirror of
https://github.com/lunarmodules/luafilesystem.git
synced 2026-07-25 13:13:07 +00:00
luafilesystem 1.6.0
This commit is contained in:
6
README
6
README
@@ -22,6 +22,12 @@ Please check the documentation at doc/us/ for more information.
|
|||||||
History
|
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]
|
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 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).
|
* added directory locking via lfs.lock_dir function (see the manual).
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ the underlying directory structure and file attributes.</p>
|
|||||||
|
|
||||||
<h2><a name="status"></a>Status</h2>
|
<h2><a name="status"></a>Status</h2>
|
||||||
|
|
||||||
<p>Current version is 1.5.0. It was developed for Lua 5.1.</p>
|
<p>Current version is 1.6.0. It was developed for Lua 5.1 but also
|
||||||
|
works with Lua 5.2.</p>
|
||||||
|
|
||||||
<h2><a name="download"></a>Download</h2>
|
<h2><a name="download"></a>Download</h2>
|
||||||
|
|
||||||
@@ -82,6 +83,12 @@ page.</p>
|
|||||||
<h2><a name="history"></a>History</h2>
|
<h2><a name="history"></a>History</h2>
|
||||||
|
|
||||||
<dl class="history">
|
<dl class="history">
|
||||||
|
<dt><strong>Version 1.6.0</strong> [26/Sep/2012]</dt>
|
||||||
|
<li>getcwd fix for Android</li>
|
||||||
|
<li>support for Lua 5.2</li>
|
||||||
|
<li>add lfs.link</li>
|
||||||
|
<li>other bug fixes</li>
|
||||||
|
|
||||||
<dt><strong>Version 1.5.0</strong> [20/Oct/2009]</dt>
|
<dt><strong>Version 1.5.0</strong> [20/Oct/2009]</dt>
|
||||||
<li>Added explicit next and close methods to second return value of lfs.dir
|
<li>Added explicit next and close methods to second return value of lfs.dir
|
||||||
(the directory object), for explicit iteration or explicit closing.</li>
|
(the directory object), for explicit iteration or explicit closing.</li>
|
||||||
|
|||||||
27
rockspecs/luafilesystem-1.6.0-1.rockspec
Normal file
27
rockspecs/luafilesystem-1.6.0-1.rockspec
Normal file
@@ -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" }
|
||||||
|
}
|
||||||
642
src/lfs.c
642
src/lfs.c
@@ -67,21 +67,21 @@
|
|||||||
#if (LUA_VERSION_NUM == 502)
|
#if (LUA_VERSION_NUM == 502)
|
||||||
#undef luaL_register
|
#undef luaL_register
|
||||||
#define luaL_register(L,n,f) \
|
#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
|
#endif
|
||||||
|
|
||||||
/* Define 'strerror' for systems that do not implement it */
|
/* Define 'strerror' for systems that do not implement it */
|
||||||
#ifdef NO_STRERROR
|
#ifdef NO_STRERROR
|
||||||
#define strerror(_) "System unable to describe the error"
|
#define strerror(_) "System unable to describe the error"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define 'getcwd' for systems that do not implement it */
|
/* Define 'getcwd' for systems that do not implement it */
|
||||||
#ifdef NO_GETCWD
|
#ifdef NO_GETCWD
|
||||||
#define getcwd(p,s) NULL
|
#define getcwd(p,s) NULL
|
||||||
#define getcwd_error "Function 'getcwd' not provided by system"
|
#define getcwd_error "Function 'getcwd' not provided by system"
|
||||||
#else
|
#else
|
||||||
#define getcwd_error strerror(errno)
|
#define getcwd_error strerror(errno)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define LFS_MAXPATHLEN MAX_PATH // MAX_PATH seems to be 260. Seems kind of small. Is there a better one?
|
#define LFS_MAXPATHLEN MAX_PATH // MAX_PATH seems to be 260. Seems kind of small. Is there a better one?
|
||||||
#else
|
#else
|
||||||
@@ -92,12 +92,12 @@
|
|||||||
|
|
||||||
#define DIR_METATABLE "directory metatable"
|
#define DIR_METATABLE "directory metatable"
|
||||||
typedef struct dir_data {
|
typedef struct dir_data {
|
||||||
int closed;
|
int closed;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
long hFile;
|
long hFile;
|
||||||
char pattern[MAX_PATH+1];
|
char pattern[MAX_PATH+1];
|
||||||
#else
|
#else
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
#endif
|
#endif
|
||||||
} dir_data;
|
} dir_data;
|
||||||
|
|
||||||
@@ -127,21 +127,21 @@ typedef struct dir_data {
|
|||||||
*/
|
*/
|
||||||
static int pusherror(lua_State *L, const char *info)
|
static int pusherror(lua_State *L, const char *info)
|
||||||
{
|
{
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
if (info==NULL)
|
if (info==NULL)
|
||||||
lua_pushstring(L, strerror(errno));
|
lua_pushstring(L, strerror(errno));
|
||||||
else
|
else
|
||||||
lua_pushfstring(L, "%s: %s", info, strerror(errno));
|
lua_pushfstring(L, "%s: %s", info, strerror(errno));
|
||||||
lua_pushinteger(L, errno);
|
lua_pushinteger(L, errno);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pushresult(lua_State *L, int i, const char *info)
|
static int pushresult(lua_State *L, int i, const char *info)
|
||||||
{
|
{
|
||||||
if (i==-1)
|
if (i==-1)
|
||||||
return pusherror(L, info);
|
return pusherror(L, info);
|
||||||
lua_pushinteger(L, i);
|
lua_pushinteger(L, i);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -149,16 +149,16 @@ static int pushresult(lua_State *L, int i, const char *info)
|
|||||||
** This function changes the working (current) directory
|
** This function changes the working (current) directory
|
||||||
*/
|
*/
|
||||||
static int change_dir (lua_State *L) {
|
static int change_dir (lua_State *L) {
|
||||||
const char *path = luaL_checkstring(L, 1);
|
const char *path = luaL_checkstring(L, 1);
|
||||||
if (chdir(path)) {
|
if (chdir(path)) {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushfstring (L,"Unable to change working directory to '%s'\n%s\n",
|
lua_pushfstring (L,"Unable to change working directory to '%s'\n%s\n",
|
||||||
path, chdir_error);
|
path, chdir_error);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushboolean (L, 1);
|
lua_pushboolean (L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -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.
|
** 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) {
|
static FILE *check_file (lua_State *L, int idx, const char *funcname) {
|
||||||
FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*");
|
FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*");
|
||||||
if (fh == NULL) {
|
if (fh == NULL) {
|
||||||
luaL_error (L, "%s: not a file", funcname);
|
luaL_error (L, "%s: not a file", funcname);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (*fh == NULL) {
|
} else if (*fh == NULL) {
|
||||||
luaL_error (L, "%s: closed file", funcname);
|
luaL_error (L, "%s: closed file", funcname);
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
return *fh;
|
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) {
|
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
|
#ifdef _WIN32
|
||||||
/* lkmode valid values are:
|
/* 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_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_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.
|
||||||
LK_NBRLCK Same as _LK_NBLCK.
|
LK_NBRLCK Same as _LK_NBLCK.
|
||||||
LK_RLCK Same as _LK_LOCK.
|
LK_RLCK Same as _LK_LOCK.
|
||||||
LK_UNLCK Unlocks the specified bytes, which must have been previously locked.
|
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.
|
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
|
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp
|
||||||
*/
|
*/
|
||||||
int lkmode;
|
int lkmode;
|
||||||
switch (*mode) {
|
switch (*mode) {
|
||||||
case 'r': lkmode = LK_NBLCK; break;
|
case 'r': lkmode = LK_NBLCK; break;
|
||||||
case 'w': lkmode = LK_NBLCK; break;
|
case 'w': lkmode = LK_NBLCK; break;
|
||||||
case 'u': lkmode = LK_UNLCK; break;
|
case 'u': lkmode = LK_UNLCK; break;
|
||||||
default : return luaL_error (L, "%s: invalid mode", funcname);
|
default : return luaL_error (L, "%s: invalid mode", funcname);
|
||||||
}
|
}
|
||||||
if (!len) {
|
if (!len) {
|
||||||
fseek (fh, 0L, SEEK_END);
|
fseek (fh, 0L, SEEK_END);
|
||||||
len = ftell (fh);
|
len = ftell (fh);
|
||||||
}
|
}
|
||||||
fseek (fh, start, SEEK_SET);
|
fseek (fh, start, SEEK_SET);
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
code = locking (fileno(fh), lkmode, len);
|
code = locking (fileno(fh), lkmode, len);
|
||||||
#else
|
#else
|
||||||
code = _locking (fileno(fh), lkmode, len);
|
code = _locking (fileno(fh), lkmode, len);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
struct flock f;
|
struct flock f;
|
||||||
switch (*mode) {
|
switch (*mode) {
|
||||||
case 'w': f.l_type = F_WRLCK; break;
|
case 'w': f.l_type = F_WRLCK; break;
|
||||||
case 'r': f.l_type = F_RDLCK; break;
|
case 'r': f.l_type = F_RDLCK; break;
|
||||||
case 'u': f.l_type = F_UNLCK; break;
|
case 'u': f.l_type = F_UNLCK; break;
|
||||||
default : return luaL_error (L, "%s: invalid mode", funcname);
|
default : return luaL_error (L, "%s: invalid mode", funcname);
|
||||||
}
|
}
|
||||||
f.l_whence = SEEK_SET;
|
f.l_whence = SEEK_SET;
|
||||||
f.l_start = (off_t)start;
|
f.l_start = (off_t)start;
|
||||||
f.l_len = (off_t)len;
|
f.l_len = (off_t)len;
|
||||||
code = fcntl (fileno(fh), F_SETLK, &f);
|
code = fcntl (fileno(fh), F_SETLK, &f);
|
||||||
#endif
|
#endif
|
||||||
return (code != -1);
|
return (code != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -263,14 +263,14 @@ static int lfs_lock_dir(lua_State *L) {
|
|||||||
}
|
}
|
||||||
strcpy(ln, path); strcat(ln, lockfile);
|
strcpy(ln, path); strcat(ln, lockfile);
|
||||||
if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW,
|
if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW,
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) {
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) {
|
||||||
int en = GetLastError();
|
int en = GetLastError();
|
||||||
free(ln); lua_pushnil(L);
|
free(ln); lua_pushnil(L);
|
||||||
if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION)
|
if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION)
|
||||||
lua_pushstring(L, "File exists");
|
lua_pushstring(L, "File exists");
|
||||||
else
|
else
|
||||||
lua_pushstring(L, strerror(en));
|
lua_pushstring(L, strerror(en));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
free(ln);
|
free(ln);
|
||||||
lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock));
|
lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock));
|
||||||
@@ -358,18 +358,18 @@ static int lfs_f_setmode(lua_State *L) {
|
|||||||
** @param #4 Number with length (optional).
|
** @param #4 Number with length (optional).
|
||||||
*/
|
*/
|
||||||
static int file_lock (lua_State *L) {
|
static int file_lock (lua_State *L) {
|
||||||
FILE *fh = check_file (L, 1, "lock");
|
FILE *fh = check_file (L, 1, "lock");
|
||||||
const char *mode = luaL_checkstring (L, 2);
|
const char *mode = luaL_checkstring (L, 2);
|
||||||
const long start = luaL_optlong (L, 3, 0);
|
const long start = luaL_optlong (L, 3, 0);
|
||||||
long len = luaL_optlong (L, 4, 0);
|
long len = luaL_optlong (L, 4, 0);
|
||||||
if (_file_lock (L, fh, mode, start, len, "lock")) {
|
if (_file_lock (L, fh, mode, start, len, "lock")) {
|
||||||
lua_pushboolean (L, 1);
|
lua_pushboolean (L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushfstring (L, "%s", strerror(errno));
|
lua_pushfstring (L, "%s", strerror(errno));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -380,17 +380,17 @@ static int file_lock (lua_State *L) {
|
|||||||
** @param #3 Number with length (optional).
|
** @param #3 Number with length (optional).
|
||||||
*/
|
*/
|
||||||
static int file_unlock (lua_State *L) {
|
static int file_unlock (lua_State *L) {
|
||||||
FILE *fh = check_file (L, 1, "unlock");
|
FILE *fh = check_file (L, 1, "unlock");
|
||||||
const long start = luaL_optlong (L, 2, 0);
|
const long start = luaL_optlong (L, 2, 0);
|
||||||
long len = luaL_optlong (L, 3, 0);
|
long len = luaL_optlong (L, 3, 0);
|
||||||
if (_file_lock (L, fh, "u", start, len, "unlock")) {
|
if (_file_lock (L, fh, "u", start, len, "unlock")) {
|
||||||
lua_pushboolean (L, 1);
|
lua_pushboolean (L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushfstring (L, "%s", strerror(errno));
|
lua_pushfstring (L, "%s", strerror(errno));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -403,10 +403,10 @@ static int file_unlock (lua_State *L) {
|
|||||||
static int make_link(lua_State *L)
|
static int make_link(lua_State *L)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
const char *oldpath = luaL_checkstring(L, 1);
|
const char *oldpath = luaL_checkstring(L, 1);
|
||||||
const char *newpath = luaL_checkstring(L, 2);
|
const char *newpath = luaL_checkstring(L, 2);
|
||||||
return pushresult(L,
|
return pushresult(L,
|
||||||
(lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL);
|
(lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL);
|
||||||
#else
|
#else
|
||||||
pusherror(L, "make_link is not supported on Windows");
|
pusherror(L, "make_link is not supported on Windows");
|
||||||
#endif
|
#endif
|
||||||
@@ -418,21 +418,21 @@ static int make_link(lua_State *L)
|
|||||||
** @param #1 Directory path.
|
** @param #1 Directory path.
|
||||||
*/
|
*/
|
||||||
static int make_dir (lua_State *L) {
|
static int make_dir (lua_State *L) {
|
||||||
const char *path = luaL_checkstring (L, 1);
|
const char *path = luaL_checkstring (L, 1);
|
||||||
int fail;
|
int fail;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
fail = _mkdir (path);
|
fail = _mkdir (path);
|
||||||
#else
|
#else
|
||||||
fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
|
fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
|
||||||
S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH );
|
S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH );
|
||||||
#endif
|
#endif
|
||||||
if (fail) {
|
if (fail) {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushfstring (L, "%s", strerror(errno));
|
lua_pushfstring (L, "%s", strerror(errno));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
lua_pushboolean (L, 1);
|
lua_pushboolean (L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -440,18 +440,18 @@ static int make_dir (lua_State *L) {
|
|||||||
** @param #1 Directory path.
|
** @param #1 Directory path.
|
||||||
*/
|
*/
|
||||||
static int remove_dir (lua_State *L) {
|
static int remove_dir (lua_State *L) {
|
||||||
const char *path = luaL_checkstring (L, 1);
|
const char *path = luaL_checkstring (L, 1);
|
||||||
int fail;
|
int fail;
|
||||||
|
|
||||||
fail = rmdir (path);
|
fail = rmdir (path);
|
||||||
|
|
||||||
if (fail) {
|
if (fail) {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushfstring (L, "%s", strerror(errno));
|
lua_pushfstring (L, "%s", strerror(errno));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
lua_pushboolean (L, 1);
|
lua_pushboolean (L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -459,44 +459,44 @@ static int remove_dir (lua_State *L) {
|
|||||||
*/
|
*/
|
||||||
static int dir_iter (lua_State *L) {
|
static int dir_iter (lua_State *L) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
struct _finddata_t c_file;
|
struct _finddata_t c_file;
|
||||||
#else
|
#else
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
#endif
|
#endif
|
||||||
dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE);
|
dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE);
|
||||||
luaL_argcheck (L, d->closed == 0, 1, "closed directory");
|
luaL_argcheck (L, d->closed == 0, 1, "closed directory");
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (d->hFile == 0L) { /* first entry */
|
if (d->hFile == 0L) { /* first entry */
|
||||||
if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) {
|
if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushstring (L, strerror (errno));
|
lua_pushstring (L, strerror (errno));
|
||||||
d->closed = 1;
|
d->closed = 1;
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
lua_pushstring (L, c_file.name);
|
lua_pushstring (L, c_file.name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else { /* next entry */
|
} else { /* next entry */
|
||||||
if (_findnext (d->hFile, &c_file) == -1L) {
|
if (_findnext (d->hFile, &c_file) == -1L) {
|
||||||
/* no more entries => close directory */
|
/* no more entries => close directory */
|
||||||
_findclose (d->hFile);
|
_findclose (d->hFile);
|
||||||
d->closed = 1;
|
d->closed = 1;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
lua_pushstring (L, c_file.name);
|
lua_pushstring (L, c_file.name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if ((entry = readdir (d->dir)) != NULL) {
|
if ((entry = readdir (d->dir)) != NULL) {
|
||||||
lua_pushstring (L, entry->d_name);
|
lua_pushstring (L, entry->d_name);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
/* no more entries => close directory */
|
/* no more entries => close directory */
|
||||||
closedir (d->dir);
|
closedir (d->dir);
|
||||||
d->closed = 1;
|
d->closed = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,18 +505,18 @@ static int dir_iter (lua_State *L) {
|
|||||||
** Closes directory iterators
|
** Closes directory iterators
|
||||||
*/
|
*/
|
||||||
static int dir_close (lua_State *L) {
|
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
|
#ifdef _WIN32
|
||||||
if (!d->closed && d->hFile) {
|
if (!d->closed && d->hFile) {
|
||||||
_findclose (d->hFile);
|
_findclose (d->hFile);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!d->closed && d->dir) {
|
if (!d->closed && d->dir) {
|
||||||
closedir (d->dir);
|
closedir (d->dir);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
d->closed = 1;
|
d->closed = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -524,25 +524,25 @@ static int dir_close (lua_State *L) {
|
|||||||
** Factory of directory iterators
|
** Factory of directory iterators
|
||||||
*/
|
*/
|
||||||
static int dir_iter_factory (lua_State *L) {
|
static int dir_iter_factory (lua_State *L) {
|
||||||
const char *path = luaL_checkstring (L, 1);
|
const char *path = luaL_checkstring (L, 1);
|
||||||
dir_data *d;
|
dir_data *d;
|
||||||
lua_pushcfunction (L, dir_iter);
|
lua_pushcfunction (L, dir_iter);
|
||||||
d = (dir_data *) lua_newuserdata (L, sizeof(dir_data));
|
d = (dir_data *) lua_newuserdata (L, sizeof(dir_data));
|
||||||
luaL_getmetatable (L, DIR_METATABLE);
|
luaL_getmetatable (L, DIR_METATABLE);
|
||||||
lua_setmetatable (L, -2);
|
lua_setmetatable (L, -2);
|
||||||
d->closed = 0;
|
d->closed = 0;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
d->hFile = 0L;
|
d->hFile = 0L;
|
||||||
if (strlen(path) > MAX_PATH-2)
|
if (strlen(path) > MAX_PATH-2)
|
||||||
luaL_error (L, "path too long: %s", path);
|
luaL_error (L, "path too long: %s", path);
|
||||||
else
|
else
|
||||||
sprintf (d->pattern, "%s/*", path);
|
sprintf (d->pattern, "%s/*", path);
|
||||||
#else
|
#else
|
||||||
d->dir = opendir (path);
|
d->dir = opendir (path);
|
||||||
if (d->dir == NULL)
|
if (d->dir == NULL)
|
||||||
luaL_error (L, "cannot open %s: %s", path, strerror (errno));
|
luaL_error (L, "cannot open %s: %s", path, strerror (errno));
|
||||||
#endif
|
#endif
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -550,38 +550,38 @@ static int dir_iter_factory (lua_State *L) {
|
|||||||
** Creates directory metatable.
|
** Creates directory metatable.
|
||||||
*/
|
*/
|
||||||
static int dir_create_meta (lua_State *L) {
|
static int dir_create_meta (lua_State *L) {
|
||||||
luaL_newmetatable (L, DIR_METATABLE);
|
luaL_newmetatable (L, DIR_METATABLE);
|
||||||
|
|
||||||
/* Method table */
|
/* Method table */
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_pushcfunction (L, dir_iter);
|
lua_pushcfunction (L, dir_iter);
|
||||||
lua_setfield(L, -2, "next");
|
lua_setfield(L, -2, "next");
|
||||||
lua_pushcfunction (L, dir_close);
|
lua_pushcfunction (L, dir_close);
|
||||||
lua_setfield(L, -2, "close");
|
lua_setfield(L, -2, "close");
|
||||||
|
|
||||||
/* Metamethods */
|
/* Metamethods */
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
lua_pushcfunction (L, dir_close);
|
lua_pushcfunction (L, dir_close);
|
||||||
lua_setfield (L, -2, "__gc");
|
lua_setfield (L, -2, "__gc");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Creates lock metatable.
|
** Creates lock metatable.
|
||||||
*/
|
*/
|
||||||
static int lock_create_meta (lua_State *L) {
|
static int lock_create_meta (lua_State *L) {
|
||||||
luaL_newmetatable (L, LOCK_METATABLE);
|
luaL_newmetatable (L, LOCK_METATABLE);
|
||||||
|
|
||||||
/* Method table */
|
/* Method table */
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_pushcfunction(L, lfs_unlock_dir);
|
lua_pushcfunction(L, lfs_unlock_dir);
|
||||||
lua_setfield(L, -2, "free");
|
lua_setfield(L, -2, "free");
|
||||||
|
|
||||||
/* Metamethods */
|
/* Metamethods */
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
lua_pushcfunction(L, lfs_unlock_dir);
|
lua_pushcfunction(L, lfs_unlock_dir);
|
||||||
lua_setfield(L, -2, "__gc");
|
lua_setfield(L, -2, "__gc");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -621,17 +621,17 @@ static const char *mode2string (mode_t mode) {
|
|||||||
else if ( S_ISDIR(mode) )
|
else if ( S_ISDIR(mode) )
|
||||||
return "directory";
|
return "directory";
|
||||||
else if ( S_ISLNK(mode) )
|
else if ( S_ISLNK(mode) )
|
||||||
return "link";
|
return "link";
|
||||||
else if ( S_ISSOCK(mode) )
|
else if ( S_ISSOCK(mode) )
|
||||||
return "socket";
|
return "socket";
|
||||||
else if ( S_ISFIFO(mode) )
|
else if ( S_ISFIFO(mode) )
|
||||||
return "named pipe";
|
return "named pipe";
|
||||||
else if ( S_ISCHR(mode) )
|
else if ( S_ISCHR(mode) )
|
||||||
return "char device";
|
return "char device";
|
||||||
else if ( S_ISBLK(mode) )
|
else if ( S_ISBLK(mode) )
|
||||||
return "block device";
|
return "block device";
|
||||||
else
|
else
|
||||||
return "other";
|
return "other";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -639,78 +639,78 @@ static const char *mode2string (mode_t mode) {
|
|||||||
** Set access time and modification values for file
|
** Set access time and modification values for file
|
||||||
*/
|
*/
|
||||||
static int file_utime (lua_State *L) {
|
static int file_utime (lua_State *L) {
|
||||||
const char *file = luaL_checkstring (L, 1);
|
const char *file = luaL_checkstring (L, 1);
|
||||||
struct utimbuf utb, *buf;
|
struct utimbuf utb, *buf;
|
||||||
|
|
||||||
if (lua_gettop (L) == 1) /* set to current date/time */
|
if (lua_gettop (L) == 1) /* set to current date/time */
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
else {
|
else {
|
||||||
utb.actime = (time_t)luaL_optnumber (L, 2, 0);
|
utb.actime = (time_t)luaL_optnumber (L, 2, 0);
|
||||||
utb.modtime = (time_t)luaL_optnumber (L, 3, utb.actime);
|
utb.modtime = (time_t)luaL_optnumber (L, 3, utb.actime);
|
||||||
buf = &utb;
|
buf = &utb;
|
||||||
}
|
}
|
||||||
if (utime (file, buf)) {
|
if (utime (file, buf)) {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushfstring (L, "%s", strerror (errno));
|
lua_pushfstring (L, "%s", strerror (errno));
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
lua_pushboolean (L, 1);
|
lua_pushboolean (L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* inode protection mode */
|
/* inode protection mode */
|
||||||
static void push_st_mode (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* device inode resides on */
|
||||||
static void push_st_dev (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* inode's number */
|
||||||
static void push_st_ino (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* number of hard links to the file */
|
||||||
static void push_st_nlink (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* user-id of owner */
|
||||||
static void push_st_uid (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* group-id of owner */
|
||||||
static void push_st_gid (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* device type, for special file inode */
|
||||||
static void push_st_rdev (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* time of last access */
|
||||||
static void push_st_atime (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* time of last data modification */
|
||||||
static void push_st_mtime (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* time of last file status change */
|
||||||
static void push_st_ctime (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* file size, in bytes */
|
||||||
static void push_st_size (lua_State *L, STAT_STRUCT *info) {
|
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
|
#ifndef _WIN32
|
||||||
/* blocks allocated for file */
|
/* blocks allocated for file */
|
||||||
static void push_st_blocks (lua_State *L, STAT_STRUCT *info) {
|
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 */
|
/* optimal file system I/O blocksize */
|
||||||
static void push_st_blksize (lua_State *L, STAT_STRUCT *info) {
|
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
|
#endif
|
||||||
static void push_invalid (lua_State *L, STAT_STRUCT *info) {
|
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);
|
typedef void (*_push_function) (lua_State *L, STAT_STRUCT *info);
|
||||||
|
|
||||||
struct _stat_members {
|
struct _stat_members {
|
||||||
const char *name;
|
const char *name;
|
||||||
_push_function push;
|
_push_function push;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _stat_members members[] = {
|
struct _stat_members members[] = {
|
||||||
{ "mode", push_st_mode },
|
{ "mode", push_st_mode },
|
||||||
{ "dev", push_st_dev },
|
{ "dev", push_st_dev },
|
||||||
{ "ino", push_st_ino },
|
{ "ino", push_st_ino },
|
||||||
{ "nlink", push_st_nlink },
|
{ "nlink", push_st_nlink },
|
||||||
{ "uid", push_st_uid },
|
{ "uid", push_st_uid },
|
||||||
{ "gid", push_st_gid },
|
{ "gid", push_st_gid },
|
||||||
{ "rdev", push_st_rdev },
|
{ "rdev", push_st_rdev },
|
||||||
{ "access", push_st_atime },
|
{ "access", push_st_atime },
|
||||||
{ "modification", push_st_mtime },
|
{ "modification", push_st_mtime },
|
||||||
{ "change", push_st_ctime },
|
{ "change", push_st_ctime },
|
||||||
{ "size", push_st_size },
|
{ "size", push_st_size },
|
||||||
{ "permissions", push_st_perm },
|
{ "permissions", push_st_perm },
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
{ "blocks", push_st_blocks },
|
{ "blocks", push_st_blocks },
|
||||||
{ "blksize", push_st_blksize },
|
{ "blksize", push_st_blksize },
|
||||||
#endif
|
#endif
|
||||||
{ NULL, push_invalid }
|
{ NULL, push_invalid }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Get file or symbolic link information
|
** Get file or symbolic link information
|
||||||
*/
|
*/
|
||||||
static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
|
static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
|
||||||
int i;
|
int i;
|
||||||
STAT_STRUCT info;
|
STAT_STRUCT info;
|
||||||
const char *file = luaL_checkstring (L, 1);
|
const char *file = luaL_checkstring (L, 1);
|
||||||
|
|
||||||
if (st(file, &info)) {
|
if (st(file, &info)) {
|
||||||
lua_pushnil (L);
|
lua_pushnil (L);
|
||||||
lua_pushfstring (L, "cannot obtain information from file `%s'", file);
|
lua_pushfstring (L, "cannot obtain information from file `%s'", file);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (lua_isstring (L, 2)) {
|
if (lua_isstring (L, 2)) {
|
||||||
int v;
|
int v;
|
||||||
const char *member = lua_tostring (L, 2);
|
const char *member = lua_tostring (L, 2);
|
||||||
if (strcmp (member, "mode") == 0) v = 0;
|
if (strcmp (member, "mode") == 0) v = 0;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
else if (strcmp (member, "blocks") == 0) v = 11;
|
else if (strcmp (member, "blocks") == 0) v = 11;
|
||||||
else if (strcmp (member, "blksize") == 0) v = 12;
|
else if (strcmp (member, "blksize") == 0) v = 12;
|
||||||
#endif
|
#endif
|
||||||
else /* look for member */
|
else /* look for member */
|
||||||
for (v = 1; members[v].name; v++)
|
for (v = 1; members[v].name; v++)
|
||||||
if (*members[v].name == *member)
|
if (*members[v].name == *member)
|
||||||
break;
|
break;
|
||||||
/* push member value and return */
|
/* push member value and return */
|
||||||
members[v].push (L, &info);
|
members[v].push (L, &info);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (!lua_istable (L, 2))
|
} else if (!lua_istable (L, 2))
|
||||||
/* creates a table if none is given */
|
/* creates a table if none is given */
|
||||||
lua_newtable (L);
|
lua_newtable (L);
|
||||||
/* stores all members in table on top of the stack */
|
/* stores all members in table on top of the stack */
|
||||||
for (i = 0; members[i].name; i++) {
|
for (i = 0; members[i].name; i++) {
|
||||||
lua_pushstring (L, members[i].name);
|
lua_pushstring (L, members[i].name);
|
||||||
members[i].push (L, &info);
|
members[i].push (L, &info);
|
||||||
lua_rawset (L, -3);
|
lua_rawset (L, -3);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -832,7 +832,7 @@ static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
|
|||||||
** Get file information using stat.
|
** Get file information using stat.
|
||||||
*/
|
*/
|
||||||
static int file_info (lua_State *L) {
|
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.
|
** Get symbolic link information using lstat.
|
||||||
*/
|
*/
|
||||||
static int link_info (lua_State *L) {
|
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.
|
** Assumes the table is on top of the stack.
|
||||||
*/
|
*/
|
||||||
static void set_info (lua_State *L) {
|
static void set_info (lua_State *L) {
|
||||||
lua_pushliteral (L, "_COPYRIGHT");
|
lua_pushliteral (L, "_COPYRIGHT");
|
||||||
lua_pushliteral (L, "Copyright (C) 2003-2009 Kepler Project");
|
lua_pushliteral (L, "Copyright (C) 2003-2012 Kepler Project");
|
||||||
lua_settable (L, -3);
|
lua_settable (L, -3);
|
||||||
lua_pushliteral (L, "_DESCRIPTION");
|
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_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_settable (L, -3);
|
||||||
lua_pushliteral (L, "_VERSION");
|
lua_pushliteral (L, "_VERSION");
|
||||||
lua_pushliteral (L, "LuaFileSystem 1.5.0");
|
lua_pushliteral (L, "LuaFileSystem 1.6.0");
|
||||||
lua_settable (L, -3);
|
lua_settable (L, -3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const struct luaL_Reg fslib[] = {
|
static const struct luaL_Reg fslib[] = {
|
||||||
{"attributes", file_info},
|
{"attributes", file_info},
|
||||||
{"chdir", change_dir},
|
{"chdir", change_dir},
|
||||||
{"currentdir", get_dir},
|
{"currentdir", get_dir},
|
||||||
{"dir", dir_iter_factory},
|
{"dir", dir_iter_factory},
|
||||||
{"link", make_link},
|
{"link", make_link},
|
||||||
{"lock", file_lock},
|
{"lock", file_lock},
|
||||||
{"mkdir", make_dir},
|
{"mkdir", make_dir},
|
||||||
{"rmdir", remove_dir},
|
{"rmdir", remove_dir},
|
||||||
{"symlinkattributes", link_info},
|
{"symlinkattributes", link_info},
|
||||||
{"setmode", lfs_f_setmode},
|
{"setmode", lfs_f_setmode},
|
||||||
{"touch", file_utime},
|
{"touch", file_utime},
|
||||||
{"unlock", file_unlock},
|
{"unlock", file_unlock},
|
||||||
{"lock_dir", lfs_lock_dir},
|
{"lock_dir", lfs_lock_dir},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
#if LUA_VERSION_NUM > 501
|
#if LUA_VERSION_NUM > 501
|
||||||
static void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l)
|
static void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l)
|
||||||
{
|
{
|
||||||
luaL_newlib (L, l);
|
luaL_newlib (L, l);
|
||||||
lua_pushvalue (L, -1);
|
lua_pushvalue (L, -1);
|
||||||
lua_setglobal (L, libname);
|
lua_setglobal (L, libname);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int luaopen_lfs (lua_State *L) {
|
int luaopen_lfs (lua_State *L) {
|
||||||
dir_create_meta (L);
|
dir_create_meta (L);
|
||||||
lock_create_meta (L);
|
lock_create_meta (L);
|
||||||
luaL_register (L, "lfs", fslib);
|
luaL_register (L, "lfs", fslib);
|
||||||
set_info (L);
|
set_info (L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,22 +7,25 @@ local upper = ".."
|
|||||||
local lfs = require"lfs"
|
local lfs = require"lfs"
|
||||||
print (lfs._VERSION)
|
print (lfs._VERSION)
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
function attrdir (path)
|
function attrdir (path)
|
||||||
for file in lfs.dir(path) do
|
for file in lfs.dir(path) do
|
||||||
if file ~= "." and file ~= ".." then
|
if file ~= "." and file ~= ".." then
|
||||||
local f = path..sep..file
|
local f = path..sep..file
|
||||||
print ("\t=> "..f.." <=")
|
print ("\t=> "..f.." <=")
|
||||||
local attr = lfs.attributes (f)
|
local attr = lfs.attributes (f)
|
||||||
assert (type(attr) == "table")
|
assert (type(attr) == "table")
|
||||||
if attr.mode == "directory" then
|
if attr.mode == "directory" then
|
||||||
attrdir (f)
|
attrdir (f)
|
||||||
else
|
else
|
||||||
for name, value in pairs(attr) do
|
for name, value in pairs(attr) do
|
||||||
print (name, value)
|
print (name, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Checking changing directories
|
-- 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.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")
|
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
|
-- Changing creating and removing directories
|
||||||
local tmpdir = current..sep.."lfs_tmp_dir"
|
local tmpdir = current..sep.."lfs_tmp_dir"
|
||||||
local tmpfile = tmpdir..sep.."tmp_file"
|
local tmpfile = tmpdir..sep.."tmp_file"
|
||||||
@@ -44,15 +50,21 @@ if lfs.chdir (tmpdir) then
|
|||||||
assert (lfs.rmdir (tmpdir), "could not remove directory from previous test")
|
assert (lfs.rmdir (tmpdir), "could not remove directory from previous test")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- tries to create a directory
|
-- tries to create a directory
|
||||||
assert (lfs.mkdir (tmpdir), "could not make a new directory")
|
assert (lfs.mkdir (tmpdir), "could not make a new directory")
|
||||||
local attrib, errmsg = lfs.attributes (tmpdir)
|
local attrib, errmsg = lfs.attributes (tmpdir)
|
||||||
if not attrib then
|
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
|
end
|
||||||
local f = io.open(tmpfile, "w")
|
local f = io.open(tmpfile, "w")
|
||||||
f:close()
|
f:close()
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Change access time
|
-- Change access time
|
||||||
local testdate = os.time({ year = 2007, day = 10, month = 2, hour=0})
|
local testdate = os.time({ year = 2007, day = 10, month = 2, hour=0})
|
||||||
assert (lfs.touch (tmpfile, testdate))
|
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.access == testdate, "could not set access time")
|
||||||
assert (new_att.modification == testdate, "could not set modification time")
|
assert (new_att.modification == testdate, "could not set modification time")
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Change access and modification time
|
-- Change access and modification time
|
||||||
local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0})
|
local testdate1 = os.time({ year = 2007, day = 10, month = 2, hour=0})
|
||||||
local testdate2 = os.time({ year = 2007, day = 11, 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.access == testdate2, "could not set access time")
|
||||||
assert (new_att.modification == testdate1, "could not set modification time")
|
assert (new_att.modification == testdate1, "could not set modification time")
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Checking link (does not work on Windows)
|
-- Checking link (does not work on Windows)
|
||||||
if lfs.link (tmpfile, "_a_link_for_test_", true) then
|
if lfs.link (tmpfile, "_a_link_for_test_", true) then
|
||||||
assert (lfs.attributes"_a_link_for_test_".mode == "file")
|
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_")
|
assert (os.remove"_a_hard_link_for_test_")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Checking text/binary modes (only has an effect in Windows)
|
-- Checking text/binary modes (only has an effect in Windows)
|
||||||
local f = io.open(tmpfile, "w")
|
local f = io.open(tmpfile, "w")
|
||||||
local result, mode = lfs.setmode(f, "binary")
|
local result, mode = lfs.setmode(f, "binary")
|
||||||
@@ -87,29 +108,44 @@ result, mode = lfs.setmode(f, "text")
|
|||||||
assert(result and mode == "binary")
|
assert(result and mode == "binary")
|
||||||
f:close()
|
f:close()
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Restore access time to current value
|
-- Restore access time to current value
|
||||||
assert (lfs.touch (tmpfile, attrib.access, attrib.modification))
|
assert (lfs.touch (tmpfile, attrib.access, attrib.modification))
|
||||||
new_att = assert (lfs.attributes (tmpfile))
|
new_att = assert (lfs.attributes (tmpfile))
|
||||||
assert (new_att.access == attrib.access)
|
assert (new_att.access == attrib.access)
|
||||||
assert (new_att.modification == attrib.modification)
|
assert (new_att.modification == attrib.modification)
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Remove new file and directory
|
-- Remove new file and directory
|
||||||
assert (os.remove (tmpfile), "could not remove new file")
|
assert (os.remove (tmpfile), "could not remove new file")
|
||||||
assert (lfs.rmdir (tmpdir), "could not remove new directory")
|
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")
|
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
|
-- 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 (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")
|
assert (type(lfs.attributes (upper)) == "table", "couldn't get attributes of upper directory")
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Stressing directory iterator
|
-- Stressing directory iterator
|
||||||
count = 0
|
count = 0
|
||||||
for i = 1, 4000 do
|
for i = 1, 4000 do
|
||||||
for file in lfs.dir (tmp) do
|
for file in lfs.dir (tmp) do
|
||||||
count = count + 1
|
count = count + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- Stressing directory iterator, explicit version
|
-- Stressing directory iterator, explicit version
|
||||||
count = 0
|
count = 0
|
||||||
for i = 1, 4000 do
|
for i = 1, 4000 do
|
||||||
@@ -122,6 +158,9 @@ for i = 1, 4000 do
|
|||||||
assert(not pcall(dir.next, dir))
|
assert(not pcall(dir.next, dir))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
io.write(".")
|
||||||
|
io.flush()
|
||||||
|
|
||||||
-- directory explicit close
|
-- directory explicit close
|
||||||
local iter, dir = lfs.dir(tmp)
|
local iter, dir = lfs.dir(tmp)
|
||||||
dir:close()
|
dir:close()
|
||||||
|
|||||||
Reference in New Issue
Block a user