From 080f74f785b2f30708ae797c15fca95a418b028a Mon Sep 17 00:00:00 2001 From: Peter Melnichenko Date: Thu, 30 Jun 2016 21:17:54 +0300 Subject: Fix anchor names in documentation --- doc/us/manual.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'doc/us') diff --git a/doc/us/manual.html b/doc/us/manual.html index 86c3406..f5fbaf6 100644 --- a/doc/us/manual.html +++ b/doc/us/manual.html @@ -177,7 +177,7 @@ LuaFileSystem offers the following functions: Returns true in case of success or nil plus an error string. -
lfs.lock_dir(path, [seconds_stale])
+
lfs.lock_dir(path, [seconds_stale])
Creates a lockfile (called lockfile.lfs) in path 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.
-
lfs.currentdir ()
+
lfs.currentdir ()
Returns a string with the current working directory or nil plus an error string.
-- cgit v1.2.3-55-g6feb From 32b355a9902e6ce7aae68926fc3f2d05856fc299 Mon Sep 17 00:00:00 2001 From: NiteHawk Date: Sat, 16 Jul 2016 15:35:27 +0200 Subject: Add a 'target' field for symlinkattributes. It returns the resolved path of the symlink. Original version by Hisham , modified to use a different strategy for sizing the readlink() buffer. --- doc/us/manual.html | 2 ++ src/lfs.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- tests/test.lua | 2 ++ 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'doc/us') diff --git a/doc/us/manual.html b/doc/us/manual.html index f5fbaf6..0ecb625 100644 --- a/doc/us/manual.html +++ b/doc/us/manual.html @@ -242,6 +242,8 @@ LuaFileSystem offers the following functions:
lfs.symlinkattributes (filepath [, aname])
Identical to lfs.attributes except that it obtains information about the link itself (not the file it refers to). + It also adds a target field, containing + the file name that the symlink points to. On Windows this function does not yet support links, and is identical to lfs.attributes.
diff --git a/src/lfs.c b/src/lfs.c index 446373c..93c1419 100644 --- a/src/lfs.c +++ b/src/lfs.c @@ -849,11 +849,58 @@ 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; } diff --git a/tests/test.lua b/tests/test.lua index 2842bc0..2331eec 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_") -- cgit v1.2.3-55-g6feb