2 Commits

Author SHA1 Message Date
Hisham
a1015fe395 Lua 5.1 compatibility 2016-06-20 20:40:01 -03:00
Hisham
2e068eb438 Add a 'target' field for symlinkattributes.
It returns the resolved path of the symlink.
2016-06-20 20:32:20 -03:00
10 changed files with 311 additions and 344 deletions

View File

@@ -7,16 +7,16 @@ env:
- LUA="lua 5.2" - LUA="lua 5.2"
- LUA="lua 5.3" - LUA="lua 5.3"
- LUA="luajit 2.0" - LUA="luajit 2.0"
- LUA="luajit 2.1"
before_install: before_install:
- pip install --user cpp-coveralls hererocks - pip install --user cpp-coveralls hererocks
- hererocks env --$LUA --luarocks latest - hererocks env --$LUA --luarocks latest
- export PATH="$PWD/env/bin:$PATH" - export PATH="$PWD/env/bin:$PATH"
- luarocks install Lua-cURL --server=https://luarocks.org/dev
- luarocks install lua-path - luarocks install lua-path
- luarocks install dkjson - luarocks install lua-cjson
- luarocks install luacov - luarocks install luacov
# install luacov-coveralls, but avoid installing luafilesystem # install luacov-coveralls, but avoids installing luafilesystem
- luarocks install luacov-coveralls --server=https://luarocks.org/dev --deps-mode=none - luarocks install luacov-coveralls --server=https://luarocks.org/dev --deps-mode=none
install: install:

View File

@@ -1,13 +1,12 @@
[![License](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENSE) [![Licence](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENCE.txt)
[![Build Status](https://travis-ci.org/keplerproject/luafilesystem.svg?branch=master)](https://travis-ci.org/keplerproject/luafilesystem) [![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) [![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) [![Coverage Status](https://coveralls.io/repos/keplerproject/luafilesystem/badge.png)](https://coveralls.io/r/keplerproject/luafilesystem)
# LuaFileSystem - File System Library for Lua # LuaFileSystem - File System Library for Lua
Copyright 2003-2016 Kepler Project
Copyright 2003-2017 Kepler Project http://keplerproject.github.io/luafilesystem
https://keplerproject.github.io/luafilesystem
# Description # Description
@@ -15,7 +14,7 @@ LuaFileSystem is a Lua library developed to complement the set of functions
related to file systems offered by the standard Lua distribution. 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 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.x (MIT). LuaFileSystem is free software and uses the same license as Lua 5.1
# LuaRocks Installation # LuaRocks Installation

View File

@@ -1,179 +1,182 @@
body { body {
color: #47555c; margin-left: 1em;
font-size: 16px; margin-right: 1em;
font-family: "Open Sans", sans-serif; font-family: arial, helvetica, geneva, sans-serif;
margin: 0; background-color:#ffffff; margin:0px;
padding: 0;
background: #eff4ff;
}
a:link { color: #008fee; }
a:visited { color: #008fee; }
a:hover { color: #22a7ff; }
h1 { font-size:26px; }
h2 { font-size:24px; }
h3 { font-size:18px; }
h4 { font-size:16px; }
hr {
height: 1px;
background: #c1cce4;
border: 0px;
margin: 20px 0;
} }
code { code {
font-family: "Open Sans Mono", "Andale Mono", monospace; font-family: "Andale Mono", monospace;
} }
tt { tt {
font-family: "Open Sans Mono", "Andale Mono", monospace; font-family: "Andale Mono", monospace;
} }
body, td, th { body, td, th { font-size: 11pt; }
h1, h2, h3, h4 { margin-left: 0em; }
textarea, pre, tt { font-size:10pt; }
body, td, th { color:#000000; }
small { font-size:0.85em; }
h1 { font-size:1.5em; }
h2 { font-size:1.25em; }
h3 { font-size:1.15em; }
h4 { font-size:1.06em; }
a:link { font-weight:bold; color: #004080; text-decoration: none; }
a:visited { font-weight:bold; color: #006699; text-decoration: none; }
a:link:hover { text-decoration:underline; }
hr { color:#cccccc }
img { border-width: 0px; }
h3 { padding-top: 1em; }
p { margin-left: 1em; }
p.name {
font-family: "Andale Mono", monospace;
padding-top: 1em;
margin-left: 0em;
} }
textarea, pre, tt { blockquote { margin-left: 3em; }
font-family: "Open Sans Mono", "Andale Mono", monospace;
}
img {
border-width: 0px;
}
.example { .example {
background-color: #323744; background-color: rgb(245, 245, 245);
color: white; border-top-width: 1px;
font-size: 16px; border-right-width: 1px;
padding: 16px 24px; border-bottom-width: 1px;
border-radius: 2px; border-left-width: 1px;
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
border-top-color: silver;
border-right-color: silver;
border-bottom-color: silver;
border-left-color: silver;
padding: 1em;
margin-left: 1em;
margin-right: 1em;
font-family: "Andale Mono", monospace;
font-size: smaller;
} }
div.header, div.footer { hr {
margin-left: 0em;
background: #00007f;
border: 0px;
height: 1px;
} }
#container { ul { list-style-type: disc; }
}
#product { table.index { border: 1px #00007f; }
background-color: white; table.index td { text-align: left; vertical-align: top; }
padding: 10px; table.index ul { padding-top: 0em; margin-top: 0em; }
height: 130px;
border-bottom: solid #d3dbec 1px;
}
#product big { table {
font-size: 42px; border: 1px solid black;
} border-collapse: collapse;
#product strong {
font-weight: normal;
}
#product_logo {
float: right;
}
#product_name {
padding-top: 15px;
padding-left: 30px;
font-size: 42px;
font-weight: normal;
}
#product_description {
padding-left: 30px;
color: #757779;
}
#main {
background: #eff4ff;
margin: 0;
}
#navigation {
width: 100%;
background-color: rgb(44,62,103);
padding: 10px;
margin: 0;
}
#navigation h1 {
display: none;
}
#navigation a:hover {
text-decoration: underline;
}
#navigation ul li a {
color: rgb(136, 208, 255);
font-weight: bold;
text-decoration: none;
}
#navigation ul li li a {
color: rgb(136, 208, 255);
font-weight: normal;
text-decoration: none;
}
#navigation ul {
display: inline;
color: white;
padding: 0px;
padding-top: 10px;
padding-bottom: 10px;
}
#navigation li {
display: inline;
list-style-type: none;
padding-left: 5px;
padding-right: 5px;
}
#navigation li {
padding: 10px;
padding: 10px;
}
#navigation li li {
}
#navigation li:hover a {
color: rgb(166, 238, 255);
}
#content {
padding: 20px;
width: 800px;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
th {
border: 1px solid black;
padding: 0.5em;
}
td {
border: 1px solid black;
padding: 0.5em;
}
div.header, div.footer { margin-left: 0em; }
#container {
margin-left: 1em;
margin-right: 1em;
background-color: #f0f0f0;
}
#product {
text-align: center;
border-bottom: 1px solid #cccccc;
background-color: #ffffff;
}
#product big {
font-size: 2em;
}
#product_logo {
}
#product_name {
}
#product_description {
}
#main {
background-color: #f0f0f0;
border-left: 2px solid #cccccc;
}
#navigation {
float: left;
width: 12em;
margin: 0;
vertical-align: top;
background-color: #f0f0f0;
overflow:visible;
}
#navigation h1 {
background-color:#e7e7e7;
font-size:1.1em;
color:#000000;
text-align:left;
margin:0px;
padding:0.2em;
border-top:1px solid #dddddd;
border-bottom:1px solid #dddddd;
}
#navigation ul {
font-size:1em;
list-style-type: none;
padding: 0;
margin: 1px;
}
#navigation li {
text-indent: -1em;
margin: 0em 0em 0em 0.5em;
display: block;
padding: 3px 0px 0px 12px;
}
#navigation li li a {
padding: 0px 3px 0px -1em;
}
#content {
margin-left: 12em;
padding: 1em;
border-left: 2px solid #cccccc;
border-right: 2px solid #cccccc;
background-color: #ffffff;
}
#about { #about {
display: none; clear: both;
} margin: 0;
dl.reference {
background-color: white;
padding: 20px;
border: solid #d3dbec 1px;
}
dl.reference dt {
padding: 5px; padding: 5px;
padding-top: 25px; border-top: 2px solid #cccccc;
color: #637bbc; background-color: #ffffff;
}
dl.reference dl dt {
padding-top: 5px;
color: #637383;
}
dl.reference dd {
} }
@media print { @media print {

View File

@@ -70,30 +70,17 @@ 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.7.0. It works with Lua 5.1, 5.2 and 5.3, and it runs on various <p>Current version is 1.6.3. It works with Lua 5.1, 5.2 and 5.3.</p>
flavors of Unix (including Linux, BSDs, macOS) and Windows.</p>
<h2><a name="download"></a>Download</h2> <h2><a name="download"></a>Download</h2>
<p>LuaFileSystem can be installed using <a href="https://luarocks.org">LuaRocks</a>: <p>LuaFileSystem source can be downloaded from its
<a href="http://github.com/keplerproject/luafilesystem">Github</a>
<pre class="example"> page.</p>
$ luarocks install luafilesystem
</pre>
<p>Its source can be found at its <a href="http://github.com/keplerproject/luafilesystem">Github</a> 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.7.0</strong> [15/Sep/2017]</dt>
<dd><ul>
<li>symlinkattributes function now provides 'target' field, containing name of the file that the symlink points to.</li>
<li>attributes, symlinkattributes, touch, mkdir, and rmdir functions now return system-dependent error code as the third value on error.</li>
<li>Fixed detection of closed files for Lua 5.2+ in setmode, lock, and unlock functions.</li>
<li>Fixed various compiler warnings.</li>
</ul></dd>
<dt><strong>Version 1.6.3</strong> [15/Jan/2015]</dt> <dt><strong>Version 1.6.3</strong> [15/Jan/2015]</dt>
<dd><ul> <dd><ul>
<li>Lua 5.3 support.</li> <li>Lua 5.3 support.</li>

View File

@@ -84,7 +84,7 @@ Ierusalimschy, Andr&eacute; Carregal and Tom&aacute;s Guisasola.
The implementation is not derived from licensed software.</p> The implementation is not derived from licensed software.</p>
<hr/> <hr/>
<p>Copyright &copy; 2003 - 2017 Kepler Project.</p> <p>Copyright &copy; 2003 Kepler Project.</p>
<p>Permission is hereby granted, free of charge, to any person <p>Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation

View File

@@ -104,7 +104,7 @@ LuaFileSystem offers the following functions:
<dl class="reference"> <dl class="reference">
<dt><a name="attributes"></a><strong><code>lfs.attributes (filepath [, aname | atable])</code></strong></dt> <dt><a name="attributes"></a><strong><code>lfs.attributes (filepath [, aname | atable])</code></strong></dt>
<dd>Returns a table with the file attributes corresponding to <dd>Returns a table with the file attributes corresponding to
<code>filepath</code> (or <code>nil</code> followed by an error message and a system-dependent error code <code>filepath</code> (or <code>nil</code> followed by an error message
in case of error). in case of error).
If the second optional argument is given and is a string, then only the value of the If the second optional argument is given and is a string, then only the value of the
named attribute is returned (this use is equivalent to named attribute is returned (this use is equivalent to
@@ -177,7 +177,7 @@ LuaFileSystem offers the following functions:
Returns <code>true</code> in case of success or <code>nil</code> plus an Returns <code>true</code> in case of success or <code>nil</code> plus an
error string.</dd> error string.</dd>
<dt><a name="lock_dir"></a><strong><code>lfs.lock_dir(path, [seconds_stale])</code></strong></dt> <dt><a name="chdir"></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 <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 exist and returns the lock. If the lock already exists checks if
it's stale, using the second parameter (default for the second 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 particular, if the lock exists and is not stale it returns the
"File exists" message.</dd> "File exists" message.</dd>
<dt><a name="currentdir"></a><strong><code>lfs.currentdir ()</code></strong></dt> <dt><a name="getcwd"></a><strong><code>lfs.currentdir ()</code></strong></dt>
<dd>Returns a string with the current working directory or <code>nil</code> <dd>Returns a string with the current working directory or <code>nil</code>
plus an error string.</dd> plus an error string.</dd>
@@ -222,14 +222,14 @@ LuaFileSystem offers the following functions:
<dt><a name="mkdir"></a><strong><code>lfs.mkdir (dirname)</code></strong></dt> <dt><a name="mkdir"></a><strong><code>lfs.mkdir (dirname)</code></strong></dt>
<dd>Creates a new directory. The argument is the name of the new <dd>Creates a new directory. The argument is the name of the new
directory.<br /> directory.<br />
Returns <code>true</code> in case of success or <code>nil</code>, an error message and Returns <code>true</code> if the operation was successful;
a system-dependent error code in case of error. in case of error, it returns <code>nil</code> plus an error string.
</dd> </dd>
<dt><a name="rmdir"></a><strong><code>lfs.rmdir (dirname)</code></strong></dt> <dt><a name="rmdir"></a><strong><code>lfs.rmdir (dirname)</code></strong></dt>
<dd>Removes an existing directory. The argument is the name of the directory.<br /> <dd>Removes an existing directory. The argument is the name of the directory.<br />
Returns <code>true</code> in case of success or <code>nil</code>, an error message and Returns <code>true</code> if the operation was successful;
a system-dependent error code in case of error. in case of error, it returns <code>nil</code> plus an error string.</dd>
<dt><a name="setmode"></a><strong><code>lfs.setmode (file, mode)</code></strong></dt> <dt><a name="setmode"></a><strong><code>lfs.setmode (file, mode)</code></strong></dt>
<dd>Sets the writing mode for a file. The mode string can be either <code>"binary"</code> or <code>"text"</code>. <dd>Sets the writing mode for a file. The mode string can be either <code>"binary"</code> or <code>"text"</code>.
@@ -257,8 +257,8 @@ LuaFileSystem offers the following functions:
Lua standard function <code>os.time</code>). Lua standard function <code>os.time</code>).
If the modification time is omitted, the access time provided is used; If the modification time is omitted, the access time provided is used;
if both times are omitted, the current time is used.<br /> if both times are omitted, the current time is used.<br />
Returns <code>true</code> in case of success or <code>nil</code>, an error message and Returns <code>true</code> if the operation was successful;
a system-dependent error code in case of error. in case of error, it returns <code>nil</code> plus an error string.
</dd> </dd>
<dt><a name="unlock"></a><strong><code>lfs.unlock (filehandle[, start[, length]])</code></strong></dt> <dt><a name="unlock"></a><strong><code>lfs.unlock (filehandle[, start[, length]])</code></strong></dt>

View File

@@ -1,28 +0,0 @@
package = "LuaFileSystem"
version = "1.7.0-1"
source = {
url = "git://github.com/keplerproject/luafilesystem",
tag = "v1_7_0",
}
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.
]],
license = "MIT/X11",
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
lfs = "src/lfs.c"
},
copy_directories = {
"doc", "tests"
}
}

248
src/lfs.c
View File

@@ -1,6 +1,6 @@
/* /*
** LuaFileSystem ** LuaFileSystem
** Copyright Kepler Project 2003 - 2017 (http://keplerproject.github.io/luafilesystem) ** Copyright Kepler Project 2003 - 2016 (http://keplerproject.github.io/luafilesystem)
** **
** File system manipulation library. ** File system manipulation library.
** This library offers these functions: ** This library offers these functions:
@@ -41,26 +41,22 @@
#include <sys/stat.h> #include <sys/stat.h>
#ifdef _WIN32 #ifdef _WIN32
#include <direct.h> #include <direct.h>
#include <windows.h> #include <windows.h>
#include <io.h> #include <io.h>
#include <sys/locking.h> #include <sys/locking.h>
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#include <utime.h> #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 #else
#include <unistd.h> #include <sys/utime.h>
#include <dirent.h> #endif
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #else
#include <utime.h> #include <unistd.h>
#include <sys/param.h> /* for MAXPATHLEN */ #include <dirent.h>
#define LFS_MAXPATHLEN MAXPATHLEN #include <fcntl.h>
#include <sys/types.h>
#include <utime.h>
#endif #endif
#include <lua.h> #include <lua.h>
@@ -80,10 +76,8 @@
#endif #endif
#if LUA_VERSION_NUM >= 502 #if LUA_VERSION_NUM < 502
# define new_lib(L, l) (luaL_newlib(L, l)) # define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l))
#else
# define new_lib(L, l) (lua_newtable(L), luaL_register(L, NULL, l))
#endif #endif
/* Define 'strerror' for systems that do not implement it */ /* Define 'strerror' for systems that do not implement it */
@@ -91,6 +85,22 @@
#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 */
#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" #define DIR_METATABLE "directory metatable"
typedef struct dir_data { typedef struct dir_data {
int closed; int closed;
@@ -123,13 +133,6 @@ typedef struct dir_data {
#define LSTAT_FUNC lstat #define LSTAT_FUNC lstat
#endif #endif
#ifdef _WIN32
#define lfs_mkdir _mkdir
#else
#define lfs_mkdir(path) (mkdir((path), \
S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH))
#endif
/* /*
** Utility functions ** Utility functions
*/ */
@@ -144,13 +147,12 @@ static int pusherror(lua_State *L, const char *info)
return 3; return 3;
} }
static int pushresult(lua_State *L, int res, const char *info) { static int pushresult(lua_State *L, int i, const char *info)
if (res == -1) { {
return pusherror(L, info); if (i==-1)
} else { return pusherror(L, info);
lua_pushboolean(L, 1); lua_pushinteger(L, i);
return 1; return 1;
}
} }
@@ -176,35 +178,18 @@ static int change_dir (lua_State *L) {
** and a string describing the error ** and a string describing the error
*/ */
static int get_dir (lua_State *L) { static int get_dir (lua_State *L) {
#ifdef NO_GETCWD 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) {
lua_pushnil(L); lua_pushnil(L);
lua_pushstring(L, "Function 'getcwd' not provided by system"); lua_pushstring(L, getcwd_error);
return 2; return 2;
#else }
char *path = NULL; else {
/* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */ lua_pushstring(L, path);
size_t size = LFS_MAXPATHLEN; /* initial buffer size */ return 1;
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
} }
/* /*
@@ -432,20 +417,16 @@ static int file_unlock (lua_State *L) {
** @param #2 Name of link. ** @param #2 Name of link.
** @param #3 True if link is symbolic (optional). ** @param #3 True if link is symbolic (optional).
*/ */
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);
int res = (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath); return pushresult(L,
if (res == -1) { (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL);
return pusherror(L, NULL);
} else {
lua_pushinteger(L, 0);
return 1;
}
#else #else
errno = ENOSYS; /* = "Function not implemented" */ errno = ENOSYS; /* = "Function not implemented" */
return pushresult(L, -1, "make_link is not supported on Windows"); return pushresult(L, -1, "make_link is not supported on Windows");
#endif #endif
} }
@@ -455,8 +436,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);
return pushresult(L, lfs_mkdir(path), NULL); int fail;
#ifdef _WIN32
fail = _mkdir (path);
#else
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);
lua_pushfstring (L, "%s", strerror(errno));
return 2;
}
lua_pushboolean (L, 1);
return 1;
} }
@@ -465,8 +459,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);
return pushresult(L, rmdir(path), NULL); int fail;
fail = rmdir (path);
if (fail) {
lua_pushnil (L);
lua_pushfstring (L, "%s", strerror(errno));
return 2;
}
lua_pushboolean (L, 1);
return 1;
} }
@@ -653,24 +657,26 @@ static const char *mode2string (mode_t mode) {
/* /*
** Set access time and modification values for a file. ** Set access time and modification values for file
** @param #1 File path.
** @param #2 Access time in seconds, current time is used if missing.
** @param #3 Modification time in seconds, access time is used if missing.
*/ */
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_optinteger(L, 3, utb.actime); utb.modtime = (time_t) luaL_optinteger (L, 3, utb.actime);
buf = &utb; buf = &utb;
} }
if (utime (file, buf)) {
return pushresult(L, utime(file, buf), NULL); lua_pushnil (L);
lua_pushfstring (L, "%s", strerror (errno));
return 2;
}
lua_pushboolean (L, 1);
return 1;
} }
@@ -807,8 +813,7 @@ static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
if (st(file, &info)) { if (st(file, &info)) {
lua_pushnil(L); lua_pushnil(L);
lua_pushfstring(L, "cannot obtain information from file '%s': %s", file, strerror(errno)); lua_pushfstring(L, "cannot obtain information from file '%s': %s", file, strerror(errno));
lua_pushinteger(L, errno); return 2;
return 3;
} }
if (lua_isstring (L, 2)) { if (lua_isstring (L, 2)) {
const char *member = lua_tostring (L, 2); const char *member = lua_tostring (L, 2);
@@ -822,8 +827,7 @@ static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
/* member not found */ /* member not found */
return luaL_error(L, "invalid attribute name '%s'", member); return luaL_error(L, "invalid attribute name '%s'", member);
} }
/* creates a table if none is given, removes extra arguments */ /* creates a table if none is given */
lua_settop(L, 2);
if (!lua_istable (L, 2)) { if (!lua_istable (L, 2)) {
lua_newtable (L); lua_newtable (L);
} }
@@ -857,21 +861,37 @@ static int push_link_target(lua_State *L) {
return 0; return 0;
#else #else
const char *file = luaL_checkstring(L, 1); const char *file = luaL_checkstring(L, 1);
char *target = NULL; char *target;
int tsize, size = 256; /* size = initial buffer capacity */ int size, tsize;
while (1) { if (lua_type(L, -1) == LUA_TTABLE) {
target = realloc(target, size); /* when symlinkattributes collects the whole table,
if (!target) /* failed to allocate */ get the size from it */
lua_getfield(L, -1, "size");
int size_type = lua_type(L, -1);
if (size_type != LUA_TNUMBER) {
lua_pop(L, 1);
errno = EINVAL;
return 0;
}
size = lua_tointeger(L, -1);
lua_pop(L, 1);
} else {
/* when we are just getting 'target', we need to run
lstat ourselves to get the size */
STAT_STRUCT info;
if (LSTAT_FUNC(file, &info)) {
return 0;
}
size = info.st_size;
}
target = (char*) malloc(size + 1);
if (!target) {
return 0; return 0;
tsize = readlink(file, target, size); }
if (tsize < 0) { /* a readlink() error occurred */ tsize = readlink(file, target, size);
if (tsize != size) {
free(target); free(target);
return 0; return 0;
}
if (tsize < size)
break;
/* possibly truncated readlink() result, double size and retry */
size *= 2;
} }
target[tsize] = '\0'; target[tsize] = '\0';
lua_pushlstring(L, target, tsize); lua_pushlstring(L, target, tsize);
@@ -904,7 +924,7 @@ 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 (C) 2003-2017 Kepler Project"); lua_pushliteral(L, "Copyright (C) 2003-2016 Kepler Project");
lua_setfield(L, -2, "_COPYRIGHT"); 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_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"); lua_setfield(L, -2, "_DESCRIPTION");
@@ -933,7 +953,7 @@ static const struct luaL_Reg fslib[] = {
LFS_EXPORT int luaopen_lfs (lua_State *L) { LFS_EXPORT int luaopen_lfs (lua_State *L) {
dir_create_meta (L); dir_create_meta (L);
lock_create_meta (L); lock_create_meta (L);
new_lib (L, fslib); luaL_newlib (L, fslib);
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setglobal(L, LFS_LIBNAME); lua_setglobal(L, LFS_LIBNAME);
set_info (L); set_info (L);

View File

@@ -1,6 +1,6 @@
/* /*
** LuaFileSystem ** LuaFileSystem
** Copyright Kepler Project 2003 - 2017 (http://keplerproject.github.io/luafilesystem) ** Copyright Kepler Project 2003 - 2016 (http://keplerproject.github.io/luafilesystem)
*/ */
/* Define 'chdir' for systems that do not implement it */ /* Define 'chdir' for systems that do not implement it */

View File

@@ -132,17 +132,6 @@ for key, value in pairs(attr) do
"lfs.attributes values not consistent") "lfs.attributes values not consistent")
end 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 -- 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")
@@ -152,10 +141,7 @@ io.write(".")
io.flush() io.flush()
-- Trying to get attributes of a non-existent file -- Trying to get attributes of a non-existent file
local attr_ok, err, errno = lfs.attributes("this couldn't be an actual file") assert (lfs.attributes ("this couldn't be an actual file") == nil, "could get attributes of a non-existent file")
assert(attr_ok == nil, "could get attributes of a non-existent file")
assert(type(err) == "string", "failed lfs.attributes did not return an error message")
assert(type(errno) == "number", "failed lfs.attributes did not return error code")
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.write(".")