diff --git a/doc/us/manual.html b/doc/us/manual.html
index a7e2efb..996dc1f 100644
--- a/doc/us/manual.html
+++ b/doc/us/manual.html
@@ -206,6 +206,13 @@ LuaFileSystem offers the following functions:
Returns true if the operation was successful; in
case of error, it returns nil plus an error string.
+
+
lfs.link (old, new[, symlink])
+ Creates a link. The first argument is the object to link to
+ and the second is the name of the link. If the optional third
+ argument is true, the link will by a symbolic link (by default, a
+ hard link is created).
+
lfs.mkdir (dirname)
Creates a new directory. The argument is the name of the new
diff --git a/src/lfs.c b/src/lfs.c
index dd41df8..f33b5ae 100644
--- a/src/lfs.c
+++ b/src/lfs.c
@@ -106,6 +106,29 @@ typedef struct dir_data {
#define LSTAT_FUNC lstat
#endif
+/*
+** Utility functions
+*/
+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;
+}
+
+static int pushresult(lua_State *L, int i, const char *info)
+{
+ if (i==-1)
+ return pusherror(L, info);
+ lua_pushinteger(L, i);
+ return 1;
+}
+
+
/*
** This function changes the working (current) directory
*/
@@ -354,6 +377,25 @@ static int file_unlock (lua_State *L) {
}
+/*
+** Creates a link.
+** @param #1 Object to link to.
+** @param #2 Name of link.
+** @param #3 True if link is symbolic (optional).
+*/
+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);
+#else
+ pusherror(L, "make_link is not supported on Windows");
+#endif
+}
+
+
/*
** Creates a directory.
** @param #1 Directory path.
@@ -763,6 +805,7 @@ static const struct luaL_Reg fslib[] = {
{"chdir", change_dir},
{"currentdir", get_dir},
{"dir", dir_iter_factory},
+ {"link", make_link},
{"lock", file_lock},
{"mkdir", make_dir},
{"rmdir", remove_dir},
diff --git a/tests/test.lua b/tests/test.lua
index 81a0ab6..c4911c9 100644
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -69,11 +69,14 @@ 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")
--- Checking symbolic link information (does not work in Windows)
-if (os.execute ("ln -s "..tmpfile.." _a_link_for_test_")) then
+-- 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")
assert (lfs.symlinkattributes"_a_link_for_test_".mode == "link")
+ assert (lfs.link (tmpfile, "_a_hard_link_for_test_"))
+ assert (lfs.attributes (tmpfile, "nlink") == 2)
assert (os.remove"_a_link_for_test_")
+ assert (os.remove"_a_hard_link_for_test_")
end
-- Checking text/binary modes (only has an effect in Windows)