Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keplerproject/luafilesystem.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rw-r--r--README.md9
-rw-r--r--doc/us/license.html2
-rw-r--r--doc/us/manual.html6
-rw-r--r--src/lfs.c151
-rw-r--r--src/lfs.h2
-rw-r--r--tests/test.lua13
7 files changed, 130 insertions, 59 deletions
diff --git a/.travis.yml b/.travis.yml
index 04d46ac..38086ba 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,16 +7,16 @@ env:
- LUA="lua 5.2"
- LUA="lua 5.3"
- LUA="luajit 2.0"
+ - LUA="luajit 2.1"
before_install:
- pip install --user cpp-coveralls hererocks
- hererocks env --$LUA --luarocks latest
- export PATH="$PWD/env/bin:$PATH"
- - luarocks install Lua-cURL --server=https://luarocks.org/dev
- luarocks install lua-path
- - luarocks install lua-cjson
+ - luarocks install dkjson
- luarocks install luacov
- # install luacov-coveralls, but avoids installing luafilesystem
+ # install luacov-coveralls, but avoid installing luafilesystem
- luarocks install luacov-coveralls --server=https://luarocks.org/dev --deps-mode=none
install:
diff --git a/README.md b/README.md
index e2a806a..ee49373 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,13 @@
-[![Licence](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENCE.txt)
+[![License](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENSE)
[![Build Status](https://travis-ci.org/keplerproject/luafilesystem.svg?branch=master)](https://travis-ci.org/keplerproject/luafilesystem)
[![Build status](https://ci.appveyor.com/api/projects/status/y04s4ms7u16trw8e?svg=true)](https://ci.appveyor.com/project/ignacio/luafilesystem)
[![Coverage Status](https://coveralls.io/repos/keplerproject/luafilesystem/badge.png)](https://coveralls.io/r/keplerproject/luafilesystem)
# LuaFileSystem - File System Library for Lua
-Copyright 2003-2016 Kepler Project
-http://keplerproject.github.io/luafilesystem
+Copyright 2003-2017 Kepler Project
+
+https://keplerproject.github.io/luafilesystem
# Description
@@ -14,7 +15,7 @@ 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.
-LuaFileSystem is free software and uses the same license as Lua 5.1
+LuaFileSystem is free software and uses the same license as Lua 5.x (MIT).
# LuaRocks Installation
diff --git a/doc/us/license.html b/doc/us/license.html
index 5048c11..4f828cf 100644
--- a/doc/us/license.html
+++ b/doc/us/license.html
@@ -84,7 +84,7 @@ Ierusalimschy, André Carregal and Tomás Guisasola.
The implementation is not derived from licensed software.</p>
<hr/>
-<p>Copyright &copy; 2003 Kepler Project.</p>
+<p>Copyright &copy; 2003 - 2017 Kepler Project.</p>
<p>Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
diff --git a/doc/us/manual.html b/doc/us/manual.html
index beffe03..3555e3d 100644
--- a/doc/us/manual.html
+++ b/doc/us/manual.html
@@ -177,7 +177,7 @@ LuaFileSystem offers the following functions:
Returns <code>true</code> in case of success or <code>nil</code> plus an
error string.</dd>
- <dt><a name="chdir"></a><strong><code>lfs.lock_dir(path, [seconds_stale])</code></strong></dt>
+ <dt><a name="lock_dir"></a><strong><code>lfs.lock_dir(path, [seconds_stale])</code></strong></dt>
<dd>Creates a lockfile (called lockfile.lfs) in <code>path</code> if it does not
exist and returns the lock. If the lock already exists checks if
it's stale, using the second parameter (default for the second
@@ -187,7 +187,7 @@ LuaFileSystem offers the following functions:
particular, if the lock exists and is not stale it returns the
"File exists" message.</dd>
- <dt><a name="getcwd"></a><strong><code>lfs.currentdir ()</code></strong></dt>
+ <dt><a name="currentdir"></a><strong><code>lfs.currentdir ()</code></strong></dt>
<dd>Returns a string with the current working directory or <code>nil</code>
plus an error string.</dd>
@@ -242,6 +242,8 @@ LuaFileSystem offers the following functions:
<dt><a name="symlinkattributes"></a><strong><code>lfs.symlinkattributes (filepath [, aname])</code></strong></dt>
<dd>Identical to <a href="#attributes">lfs.attributes</a> except that
it obtains information about the link itself (not the file it refers to).
+ It also adds a <strong><code>target</code></strong> field, containing
+ the file name that the symlink points to.
On Windows this function does not yet support links, and is identical to
<code>lfs.attributes</code>.
</dd>
diff --git a/src/lfs.c b/src/lfs.c
index dd0b6af..dc799a4 100644
--- a/src/lfs.c
+++ b/src/lfs.c
@@ -1,6 +1,6 @@
/*
** LuaFileSystem
-** Copyright Kepler Project 2003 - 2016 (http://keplerproject.github.io/luafilesystem)
+** Copyright Kepler Project 2003 - 2017 (http://keplerproject.github.io/luafilesystem)
**
** File system manipulation library.
** This library offers these functions:
@@ -41,22 +41,26 @@
#include <sys/stat.h>
#ifdef _WIN32
-#include <direct.h>
-#include <windows.h>
-#include <io.h>
-#include <sys/locking.h>
-#ifdef __BORLANDC__
- #include <utime.h>
-#else
- #include <sys/utime.h>
-#endif
-#include <fcntl.h>
+ #include <direct.h>
+ #include <windows.h>
+ #include <io.h>
+ #include <sys/locking.h>
+ #ifdef __BORLANDC__
+ #include <utime.h>
+ #else
+ #include <sys/utime.h>
+ #endif
+ #include <fcntl.h>
+ /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */
+ #define LFS_MAXPATHLEN MAX_PATH
#else
-#include <unistd.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <utime.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <utime.h>
+ #include <sys/param.h> /* for MAXPATHLEN */
+ #define LFS_MAXPATHLEN MAXPATHLEN
#endif
#include <lua.h>
@@ -76,8 +80,10 @@
#endif
-#if LUA_VERSION_NUM < 502
-# define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l))
+#if LUA_VERSION_NUM >= 502
+# define new_lib(L, l) (luaL_newlib(L, l))
+#else
+# define new_lib(L, l) (lua_newtable(L), luaL_register(L, NULL, l))
#endif
/* Define 'strerror' for systems that do not implement it */
@@ -85,22 +91,6 @@
#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"
-#else
-#define getcwd_error strerror(errno)
- #ifdef _WIN32
- /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */
- #define LFS_MAXPATHLEN MAX_PATH
- #else
- /* For MAXPATHLEN: */
- #include <sys/param.h>
- #define LFS_MAXPATHLEN MAXPATHLEN
- #endif
-#endif
-
#define DIR_METATABLE "directory metatable"
typedef struct dir_data {
int closed;
@@ -186,18 +176,35 @@ static int change_dir (lua_State *L) {
** and a string describing the error
*/
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];
- if ((path = getcwd(buf, LFS_MAXPATHLEN)) == NULL) {
+#ifdef NO_GETCWD
lua_pushnil(L);
- lua_pushstring(L, getcwd_error);
+ lua_pushstring(L, "Function 'getcwd' not provided by system");
return 2;
- }
- else {
- lua_pushstring(L, path);
- return 1;
- }
+#else
+ char *path = NULL;
+ /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */
+ size_t size = LFS_MAXPATHLEN; /* initial buffer size */
+ int result;
+ while (1) {
+ path = realloc(path, size);
+ if (!path) /* failed to allocate */
+ return pusherror(L, "get_dir realloc() failed");
+ if (getcwd(path, size) != NULL) {
+ /* success, push the path to the Lua stack */
+ lua_pushstring(L, path);
+ result = 1;
+ break;
+ }
+ if (errno != ERANGE) { /* unexpected error */
+ result = pusherror(L, "get_dir getcwd() failed");
+ break;
+ }
+ /* ERANGE = insufficient buffer capacity, double size and retry */
+ size *= 2;
+ }
+ free(path);
+ return result;
+#endif
}
/*
@@ -815,7 +822,8 @@ static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
/* member not found */
return luaL_error(L, "invalid attribute name '%s'", member);
}
- /* creates a table if none is given */
+ /* creates a table if none is given, removes extra arguments */
+ lua_settop(L, 2);
if (!lua_istable (L, 2)) {
lua_newtable (L);
}
@@ -838,10 +846,57 @@ static int file_info (lua_State *L) {
/*
+** Push the symlink target to the top of the stack.
+** Assumes the file name is at position 1 of the stack.
+** Returns 1 if successful (with the target on top of the stack),
+** 0 on failure (with stack unchanged, and errno set).
+*/
+static int push_link_target(lua_State *L) {
+#ifdef _WIN32
+ errno = ENOSYS;
+ return 0;
+#else
+ const char *file = luaL_checkstring(L, 1);
+ char *target = NULL;
+ int tsize, size = 256; /* size = initial buffer capacity */
+ while (1) {
+ target = realloc(target, size);
+ if (!target) /* failed to allocate */
+ return 0;
+ tsize = readlink(file, target, size);
+ if (tsize < 0) { /* a readlink() error occurred */
+ free(target);
+ return 0;
+ }
+ if (tsize < size)
+ break;
+ /* possibly truncated readlink() result, double size and retry */
+ size *= 2;
+ }
+ target[tsize] = '\0';
+ lua_pushlstring(L, target, tsize);
+ free(target);
+ return 1;
+#endif
+}
+
+/*
** Get symbolic link information using lstat.
*/
static int link_info (lua_State *L) {
- return _file_info_ (L, LSTAT_FUNC);
+ int ret;
+ if (lua_isstring (L, 2) && (strcmp(lua_tostring(L, 2), "target") == 0)) {
+ int ok = push_link_target(L);
+ return ok ? 1 : pusherror(L, "could not obtain link target");
+ }
+ ret = _file_info_ (L, LSTAT_FUNC);
+ if (ret == 1 && lua_type(L, -1) == LUA_TTABLE) {
+ int ok = push_link_target(L);
+ if (ok) {
+ lua_setfield(L, -2, "target");
+ }
+ }
+ return ret;
}
@@ -849,7 +904,7 @@ 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 (C) 2003-2016 Kepler Project");
+ lua_pushliteral(L, "Copyright (C) 2003-2017 Kepler Project");
lua_setfield(L, -2, "_COPYRIGHT");
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_setfield(L, -2, "_DESCRIPTION");
@@ -878,7 +933,7 @@ static const struct luaL_Reg fslib[] = {
LFS_EXPORT int luaopen_lfs (lua_State *L) {
dir_create_meta (L);
lock_create_meta (L);
- luaL_newlib (L, fslib);
+ new_lib (L, fslib);
lua_pushvalue(L, -1);
lua_setglobal(L, LFS_LIBNAME);
set_info (L);
diff --git a/src/lfs.h b/src/lfs.h
index 7f7d2ab..4587564 100644
--- a/src/lfs.h
+++ b/src/lfs.h
@@ -1,6 +1,6 @@
/*
** LuaFileSystem
-** Copyright Kepler Project 2003 - 2016 (http://keplerproject.github.io/luafilesystem)
+** Copyright Kepler Project 2003 - 2017 (http://keplerproject.github.io/luafilesystem)
*/
/* Define 'chdir' for systems that do not implement it */
diff --git a/tests/test.lua b/tests/test.lua
index 193e0bd..591ee25 100644
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -91,6 +91,8 @@ io.flush()
if lfs.link (tmpfile, "_a_link_for_test_", true) then
assert (lfs.attributes"_a_link_for_test_".mode == "file")
assert (lfs.symlinkattributes"_a_link_for_test_".mode == "link")
+ assert (lfs.symlinkattributes"_a_link_for_test_".target == tmpfile)
+ assert (lfs.symlinkattributes("_a_link_for_test_", "target") == tmpfile)
assert (lfs.link (tmpfile, "_a_hard_link_for_test_"))
assert (lfs.attributes (tmpfile, "nlink") == 2)
assert (os.remove"_a_link_for_test_")
@@ -130,6 +132,17 @@ for key, value in pairs(attr) do
"lfs.attributes values not consistent")
end
+-- Check that lfs.attributes accepts a table as second argument
+local attr2 = {}
+lfs.attributes(tmpfile, attr2)
+for key, value in pairs(attr2) do
+ assert (value == lfs.attributes (tmpfile, key),
+ "lfs.attributes values with table argument not consistent")
+end
+
+-- Check that extra arguments are ignored
+lfs.attributes(tmpfile, attr2, nil)
+
-- Remove new file and directory
assert (os.remove (tmpfile), "could not remove new file")
assert (lfs.rmdir (tmpdir), "could not remove new directory")