4 Commits
v1_8_0 ... 2.0

Author SHA1 Message Date
Hisham
b1f0f80141 Merge branch 'master' into 2.0 2016-10-19 01:36:11 -04:00
Peter Melnichenko
aa18f3e127 Don't declare global 'lfs' 2016-05-05 15:24:29 +03:00
Peter Melnichenko
6d6fd631ba Add a test for success return value of lfs.link 2016-05-05 15:10:56 +03:00
Peter Melnichenko
46bbddc5a2 Return true instead of 0 on lfs.link success 2016-05-05 12:46:54 +03:00
28 changed files with 1123 additions and 1014 deletions

View File

@@ -6,20 +6,21 @@ env:
- LUA="lua 5.1" - LUA="lua 5.1"
- LUA="lua 5.2" - LUA="lua 5.2"
- LUA="lua 5.3" - LUA="lua 5.3"
- LUA="luajit 2.1" - LUA="luajit 2.0"
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:
- luarocks make CFLAGS="-O2 -fPIC -ftest-coverage -fprofile-arcs" LIBFLAG="-shared --coverage" - luarocks make rockspecs/luafilesystem-cvs-3.rockspec CFLAGS="-O2 -fPIC -ftest-coverage -fprofile-arcs" LIBFLAG="-shared --coverage"
script: script:
- lua -lluacov tests/test.lua - lua -lluacov tests/test.lua

View File

@@ -12,14 +12,14 @@ OBJS= src/$T.o
lib: src/lfs.so lib: src/lfs.so
src/lfs.so: $(OBJS) src/lfs.so: $(OBJS)
MACOSX_DEPLOYMENT_TARGET=$(MACOSX_DEPLOYMENT_TARGET); export MACOSX_DEPLOYMENT_TARGET; $(CC) $(LIB_OPTION) -o src/lfs.so $(OBJS) MACOSX_DEPLOYMENT_TARGET="10.3"; export MACOSX_DEPLOYMENT_TARGET; $(CC) $(LIB_OPTION) -o src/lfs.so $(OBJS)
test: lib test: lib
LUA_CPATH=./src/?.so lua tests/test.lua LUA_CPATH=./src/?.so lua tests/test.lua
install: install:
mkdir -p $(DESTDIR)$(LUA_LIBDIR) mkdir -p $(LUA_LIBDIR)
cp src/lfs.so $(DESTDIR)$(LUA_LIBDIR) cp src/lfs.so $(LUA_LIBDIR)
clean: clean:
rm -f src/lfs.so $(OBJS) rm -f src/lfs.so $(OBJS)

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-2020 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

@@ -11,6 +11,7 @@ environment:
- LUA: "lua 5.1" - LUA: "lua 5.1"
- LUA: "lua 5.2 --compat none" - LUA: "lua 5.2 --compat none"
- LUA: "lua 5.3 --compat none" - LUA: "lua 5.3 --compat none"
- LUA: "luajit 2.0"
- LUA: "luajit 2.1" - LUA: "luajit 2.1"
# Abuse this section so we can have a matrix with different Compiler versions # Abuse this section so we can have a matrix with different Compiler versions
@@ -29,7 +30,7 @@ before_build:
- echo "Installing external deps" - echo "Installing external deps"
build_script: build_script:
- luarocks make - luarocks make rockspecs/luafilesystem-cvs-3.rockspec
before_test: before_test:

12
config
View File

@@ -3,25 +3,21 @@
# Default installation prefix # Default installation prefix
PREFIX=/usr/local PREFIX=/usr/local
LUA_VERSION = 5.1
# System's libraries directory (where binary libraries are installed) # System's libraries directory (where binary libraries are installed)
LUA_LIBDIR= $(PREFIX)/lib/lua/$(LUA_VERSION) LUA_LIBDIR= $(PREFIX)/lib/lua/5.1
# Lua includes directory # Lua includes directory
LUA_INC += -I$(PREFIX)/include LUA_INC= $(PREFIX)/include
LUA_INC += -I/usr/include/lua$(LUA_VERSION) -I/usr/include/lua/$(LUA_VERSION)
# OS dependent # OS dependent
LIB_OPTION= -shared #for Linux LIB_OPTION= -shared #for Linux
#LIB_OPTION= -bundle -undefined dynamic_lookup #for MacOS X #LIB_OPTION= -bundle -undefined dynamic_lookup #for MacOS X
# Minimum runtime OS version on macOS LIBNAME= $T.so.$V
MACOSX_DEPLOYMENT_TARGET= 10.5
# Compilation directives # Compilation directives
WARN= -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic WARN= -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -pedantic
INCS= $(LUA_INC) INCS= -I$(LUA_INC)
CFLAGS= $(WARN) $(INCS) CFLAGS= $(WARN) $(INCS)
CC= gcc CC= gcc

View File

@@ -1,14 +1,14 @@
LUA_VERSION= 5.1
# Installation directories # Installation directories
# System's libraries directory (where binary libraries are installed) # System's libraries directory (where binary libraries are installed)
LUA_LIBDIR= "c:\lua$(LUA_VERSION)" LUA_LIBDIR= "c:\lua5.1"
# Lua includes directory # Lua includes directory
LUA_INC= "c:\lua$(LUA_VERSION)\include" LUA_INC= "c:\lua5.1\include"
# Lua library # Lua library
LUA_LIB= "c:\lua$(LUA_VERSION)\lua$(LUA_VERSION).lib" LUA_LIB= "c:\lua5.1\lua5.1.lib"
LIBNAME= $T.dll
# Compilation directives # Compilation directives
WARN= /O2 WARN= /O2

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,39 +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.8.0. It works with Lua 5.1, 5.2, 5.3 and 5.4, 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.8.0</strong> [22/Apr/2020]</dt>
<dd><ul>
<li>Lua 5.4 support</li>
<li>lfs.link and lfs.symlinkattributes now work on Windows</li>
<li>MACOSX_DEPLOYMENT_TARGET is configurable in the Makefile</li>
<li>Fallback to _POSIX_PATH_MAX when MAXPATHLEN is not avaliable</li>
<li>Fixed memory leak in case of realloc failure</li>
</ul></dd>
<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 - 2020 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

@@ -102,15 +102,15 @@ LuaFileSystem offers the following functions:
</p> </p>
<dl class="reference"> <dl class="reference">
<dt><a name="attributes"></a><strong><code>lfs.attributes (filepath [, request_name | result_table])</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 and a system-dependent error code
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
<code>lfs.attributes(filepath)[request_name]</code>, but the table is not created <code>lfs.attributes(filepath)[aname]</code>, but the table is not created
and only one attribute is retrieved from the O.S.). and only one attribute is retrieved from the O.S.).
if a table is passed as the second argument, it (<code>result_table</code>) is filled with attributes and returned instead of a new table. if a table is passed as the second argument, it is filled with attributes and returned instead of a new table.
The attributes are described as follows; The attributes are described as follows;
attribute <code>mode</code> is a string, all the others are numbers, attribute <code>mode</code> is a string, all the others are numbers,
and the time related attributes use the same time reference of and the time related attributes use the same time reference of
@@ -239,7 +239,7 @@ LuaFileSystem offers the following functions:
setting the mode has no effect, and the mode is always returned as <code>binary</code>. setting the mode has no effect, and the mode is always returned as <code>binary</code>.
</dd> </dd>
<dt><a name="symlinkattributes"></a><strong><code>lfs.symlinkattributes (filepath [, request_name])</code></strong></dt> <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 <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 obtains information about the link itself (not the file it refers to).
It also adds a <strong><code>target</code></strong> field, containing It also adds a <strong><code>target</code></strong> field, containing

View File

@@ -0,0 +1,27 @@
package = "LuaFileSystem"
version = "1.3.0-1"
source = {
url = "http://luaforge.net/frs/download.php/2679/luafilesystem-1.3.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 = "make",
build_variables = {
LUA_INC = "$(LUA_INCDIR)",
LIB_OPTION = "$(LIBFLAG)"
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)"
}
}

View File

@@ -0,0 +1,27 @@
package = "LuaFileSystem"
version = "1.4.0-1"
source = {
url = "http://luaforge.net/frs/download.php/3158/luafilesystem-1.4.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 = "make",
build_variables = {
LUA_INC = "$(LUA_INCDIR)",
LIB_OPTION = "$(LIBFLAG)"
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)"
}
}

View File

@@ -0,0 +1,43 @@
package = "LuaFileSystem"
version = "1.4.0-2"
source = {
url = "http://luaforge.net/frs/download.php/3158/luafilesystem-1.4.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 = {
platforms = {
unix = {
type = "make",
build_variables = {
LIB_OPTION = "$(LIBFLAG)",
CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)"
}
},
win32 = {
type = "make",
build_variables = {
LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)",
LUA_DIR = "$(LUADIR)",
BIN_DIR = "$(BINDIR)"
}
}
}
}

View File

@@ -0,0 +1,43 @@
package = "LuaFileSystem"
version = "1.4.1-1"
source = {
url = "http://luaforge.net/frs/download.php/3345/luafilesystem-1.4.1.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 = {
platforms = {
unix = {
type = "make",
build_variables = {
LIB_OPTION = "$(LIBFLAG)",
CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR) $(STAT64)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)"
}
},
win32 = {
type = "make",
build_variables = {
LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)",
LUA_DIR = "$(LUADIR)",
BIN_DIR = "$(BINDIR)"
}
}
}
}

View File

@@ -0,0 +1,43 @@
package = "LuaFileSystem"
version = "1.4.1rc1-1"
source = {
url = "http://luafilesystem.luaforge.net/luafilesystem-1.4.1rc1.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 = {
platforms = {
unix = {
type = "make",
build_variables = {
LIB_OPTION = "$(LIBFLAG)",
CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR) $(STAT64)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)"
}
},
win32 = {
type = "make",
build_variables = {
LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)",
LUA_DIR = "$(LUADIR)",
BIN_DIR = "$(BINDIR)"
}
}
}
}

View File

@@ -0,0 +1,26 @@
package = "LuaFileSystem"
version = "1.4.2-1"
source = {
url = "http://luaforge.net/frs/download.php/3931/luafilesystem-1.4.2.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 = "module",
modules = { lfs = "src/lfs.c" }
}

View File

@@ -0,0 +1,27 @@
package = "LuaFileSystem"
version = "1.5.0-1"
source = {
url = "http://cloud.github.com/downloads/keplerproject/luafilesystem/luafilesystem-1.5.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 = "module",
modules = { lfs = "src/lfs.c" },
copy_directories = { "doc", "tests" }
}

View 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" }
}

View File

@@ -0,0 +1,27 @@
package = "LuaFileSystem"
version = "1.6.1-1"
source = {
url = "https://github.com/downloads/keplerproject/luafilesystem/luafilesystem-1.6.1.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" }
}

View File

@@ -0,0 +1,27 @@
package = "LuaFileSystem"
version = "1.6.2-1"
source = {
url = "https://github.com/downloads/keplerproject/luafilesystem/luafilesystem-1.6.2.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" }
}

View File

@@ -1,7 +1,8 @@
package = "luafilesystem" package = "LuaFileSystem"
version = "scm-1" version = "1.6.3-1"
source = { source = {
url = "git://github.com/keplerproject/luafilesystem" url = "git://github.com/keplerproject/luafilesystem",
tag = "v_1_6_3",
} }
description = { description = {
summary = "File System Library for the Lua Programming Language", summary = "File System Library for the Lua Programming Language",
@@ -11,7 +12,7 @@ description = {
distribution. LuaFileSystem offers a portable way to access the distribution. LuaFileSystem offers a portable way to access the
underlying directory structure and file attributes. underlying directory structure and file attributes.
]], ]],
license = "MIT/X11" license = "MIT/X11",
} }
dependencies = { dependencies = {
"lua >= 5.1" "lua >= 5.1"
@@ -22,7 +23,6 @@ build = {
lfs = "src/lfs.c" lfs = "src/lfs.c"
}, },
copy_directories = { copy_directories = {
"doc", "doc", "tests"
"tests"
} }
} }

View File

@@ -0,0 +1,44 @@
package = "LuaFileSystem"
version = "cvs-1"
source = {
url = "cvs://:pserver:anonymous:@cvs.luaforge.net:/cvsroot/luafilesystem",
cvs_tag = "HEAD"
}
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 = {
platforms = {
unix = {
type = "make",
build_variables = {
LIB_OPTION = "$(LIBFLAG)",
CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)"
}
},
win32 = {
type = "make",
build_variables = {
LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
CFLAGS = "$(CFLAGS) /I$(LUA_INCDIR)",
},
install_variables = {
LUA_LIBDIR = "$(LIBDIR)",
LUA_DIR = "$(LUADIR)",
BIN_DIR = "$(BINDIR)"
}
}
}
}

View File

@@ -0,0 +1,26 @@
package = "LuaFileSystem"
version = "cvs-2"
source = {
url = "git://github.com/keplerproject/luafilesystem.git",
}
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 = "module",
modules = { lfs = "src/lfs.c" }
}

View File

@@ -0,0 +1,27 @@
package = "LuaFileSystem"
version = "cvs-3"
source = {
url = "git://github.com/keplerproject/luafilesystem.git",
}
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, < 5.4"
}
build = {
type = "builtin",
modules = { lfs = "src/lfs.c" },
copy_directories = { "doc", "tests" }
}

546
src/lfs.c
View File

@@ -1,7 +1,6 @@
/* /*
** LuaFileSystem ** LuaFileSystem
** Copyright Kepler Project 2003 - 2020 ** Copyright Kepler Project 2003 - 2016 (http://keplerproject.github.io/luafilesystem)
** (http://keplerproject.github.io/luafilesystem)
** **
** File system manipulation library. ** File system manipulation library.
** This library offers these functions: ** This library offers these functions:
@@ -30,10 +29,6 @@
#endif #endif
#endif #endif
#ifdef _WIN32
#define _WIN32_WINNT 0x600
#endif
#ifndef LFS_DO_NOT_USE_LARGE_FILE #ifndef LFS_DO_NOT_USE_LARGE_FILE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
#endif #endif
@@ -46,39 +41,26 @@
#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 #else
#include <sys/utime.h> #include <sys/utime.h>
#endif #endif
#include <fcntl.h> #include <fcntl.h>
/* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */ /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */
#define LFS_MAXPATHLEN MAX_PATH #define LFS_MAXPATHLEN MAX_PATH
#else #else
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <utime.h> #include <utime.h>
#include <sys/param.h> /* for MAXPATHLEN */ #include <sys/param.h> /* for MAXPATHLEN */
#ifdef MAXPATHLEN
#define LFS_MAXPATHLEN MAXPATHLEN #define LFS_MAXPATHLEN MAXPATHLEN
#else
#include <limits.h> /* for _POSIX_PATH_MAX */
#define LFS_MAXPATHLEN _POSIX_PATH_MAX
#endif
#endif #endif
#include <lua.h> #include <lua.h>
@@ -87,10 +69,9 @@
#include "lfs.h" #include "lfs.h"
#define LFS_VERSION "1.8.0" #define LFS_VERSION "1.6.3"
#define LFS_LIBNAME "lfs"
#if LUA_VERSION_NUM >= 503 /* Lua 5.3+ */ #if LUA_VERSION_NUM >= 503 /* Lua 5.3 */
#ifndef luaL_optlong #ifndef luaL_optlong
#define luaL_optlong luaL_optinteger #define luaL_optlong luaL_optinteger
@@ -98,10 +79,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 */
@@ -123,7 +102,6 @@ typedef struct dir_data {
#define LOCK_METATABLE "lock metatable" #define LOCK_METATABLE "lock metatable"
#ifdef _WIN32 #ifdef _WIN32
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#define lfs_setmode(file, m) (setmode(_fileno(file), m)) #define lfs_setmode(file, m) (setmode(_fileno(file), m))
#define STAT_STRUCT struct stati64 #define STAT_STRUCT struct stati64
@@ -131,45 +109,15 @@ typedef struct dir_data {
#define lfs_setmode(file, m) (_setmode(_fileno(file), m)) #define lfs_setmode(file, m) (_setmode(_fileno(file), m))
#define STAT_STRUCT struct _stati64 #define STAT_STRUCT struct _stati64
#endif #endif
#ifndef _S_IFLNK
#define _S_IFLNK 0x400
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (mode&_S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (mode&_S_IFREG)
#endif
#ifndef S_ISLNK
#define S_ISLNK(mode) (mode&_S_IFLNK)
#endif
#ifndef S_ISSOCK
#define S_ISSOCK(mode) (0)
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (0)
#endif
#ifndef S_ISCHR
#define S_ISCHR(mode) (mode&_S_IFCHR)
#endif
#ifndef S_ISBLK
#define S_ISBLK(mode) (0)
#endif
#define STAT_FUNC _stati64 #define STAT_FUNC _stati64
#define LSTAT_FUNC lfs_win32_lstat #define LSTAT_FUNC STAT_FUNC
#else #else
#define _O_TEXT 0 #define _O_TEXT 0
#define _O_BINARY 0 #define _O_BINARY 0
#define lfs_setmode(file, m) ((void)file, (void)m, 0) #define lfs_setmode(file, m) ((void)file, (void)m, 0)
#define STAT_STRUCT struct stat #define STAT_STRUCT struct stat
#define STAT_FUNC stat #define STAT_FUNC stat
#define LSTAT_FUNC lstat #define LSTAT_FUNC lstat
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@@ -179,55 +127,6 @@ typedef struct dir_data {
S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH)) S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH))
#endif #endif
#ifdef _WIN32
int lfs_win32_pusherror(lua_State * L)
{
int en = GetLastError();
lua_pushnil(L);
if (en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION)
lua_pushstring(L, "File exists");
else
lua_pushstring(L, strerror(en));
return 2;
}
#define TICKS_PER_SECOND 10000000
#define EPOCH_DIFFERENCE 11644473600LL
time_t windowsToUnixTime(FILETIME ft)
{
ULARGE_INTEGER uli;
uli.LowPart = ft.dwLowDateTime;
uli.HighPart = ft.dwHighDateTime;
return (time_t) (uli.QuadPart / TICKS_PER_SECOND - EPOCH_DIFFERENCE);
}
int lfs_win32_lstat(const char *path, STAT_STRUCT * buffer)
{
WIN32_FILE_ATTRIBUTE_DATA win32buffer;
if (GetFileAttributesEx(path, GetFileExInfoStandard, &win32buffer)) {
if (!(win32buffer.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
return STAT_FUNC(path, buffer);
}
buffer->st_mode = _S_IFLNK;
buffer->st_dev = 0;
buffer->st_ino = 0;
buffer->st_nlink = 0;
buffer->st_uid = 0;
buffer->st_gid = 0;
buffer->st_rdev = 0;
buffer->st_atime = windowsToUnixTime(win32buffer.ftLastAccessTime);
buffer->st_mtime = windowsToUnixTime(win32buffer.ftLastWriteTime);
buffer->st_ctime = windowsToUnixTime(win32buffer.ftCreationTime);
buffer->st_size = 0;
return 0;
} else {
return 1;
}
}
#endif
/* /*
** Utility functions ** Utility functions
*/ */
@@ -242,8 +141,7 @@ 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 res, const char *info) {
{
if (res == -1) { if (res == -1) {
return pusherror(L, info); return pusherror(L, info);
} else { } else {
@@ -256,8 +154,7 @@ static int pushresult(lua_State * L, int res, 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);
@@ -275,25 +172,20 @@ static int change_dir(lua_State * L)
** If unable to get the current directory, it returns nil ** If unable to get the current directory, it returns nil
** 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 #ifdef NO_GETCWD
lua_pushnil(L); lua_pushnil(L);
lua_pushstring(L, "Function 'getcwd' not provided by system"); lua_pushstring(L, "Function 'getcwd' not provided by system");
return 2; return 2;
#else #else
char *path = NULL; char *path = NULL;
/* Passing (NULL, 0) is not guaranteed to work. /* Passing (NULL, 0) is not guaranteed to work. Use a temp buffer and size instead. */
Use a temp buffer and size instead. */
size_t size = LFS_MAXPATHLEN; /* initial buffer size */ size_t size = LFS_MAXPATHLEN; /* initial buffer size */
int result; int result;
while (1) { while (1) {
char *path2 = realloc(path, size); path = realloc(path, size);
if (!path2) { /* failed to allocate */ if (!path) /* failed to allocate */
result = pusherror(L, "get_dir realloc() failed"); return pusherror(L, "get_dir realloc() failed");
break;
}
path = path2;
if (getcwd(path, size) != NULL) { if (getcwd(path, size) != NULL) {
/* success, push the path to the Lua stack */ /* success, push the path to the Lua stack */
lua_pushstring(L, path); lua_pushstring(L, path);
@@ -315,8 +207,7 @@ 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) {
{
#if LUA_VERSION_NUM == 501 #if LUA_VERSION_NUM == 501
FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*"); FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*");
if (*fh == NULL) { if (*fh == NULL) {
@@ -324,7 +215,7 @@ static FILE *check_file(lua_State * L, int idx, const char *funcname)
return 0; return 0;
} else } else
return *fh; return *fh;
#elif LUA_VERSION_NUM >= 502 && LUA_VERSION_NUM <= 504 #elif LUA_VERSION_NUM >= 502 && LUA_VERSION_NUM <= 503
luaL_Stream *fh = (luaL_Stream *)luaL_checkudata (L, idx, "FILE*"); luaL_Stream *fh = (luaL_Stream *)luaL_checkudata (L, idx, "FILE*");
if (fh->closef == 0 || fh->f == NULL) { if (fh->closef == 0 || fh->f == NULL) {
luaL_error (L, "%s: closed file", funcname); luaL_error (L, "%s: closed file", funcname);
@@ -340,41 +231,26 @@ static FILE *check_file(lua_State * L, int idx, const char *funcname)
/* /*
** **
*/ */
static int _file_lock(lua_State * L, FILE * fh, const char *mode, static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long start, long len, const char *funcname) {
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, 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.
the program immediately tries again after 1 second. LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.
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_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 LK_UNLCK Unlocks the specified bytes, which must have been previously locked.
previously locked.
Regions should be locked only briefly and should be unlocked Regions should be locked only briefly and should be unlocked before closing a file or exiting the program.
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': case 'r': lkmode = LK_NBLCK; break;
lkmode = LK_NBLCK; case 'w': lkmode = LK_NBLCK; break;
break; case 'u': lkmode = LK_UNLCK; break;
case 'w': default : return luaL_error (L, "%s: invalid mode", funcname);
lkmode = LK_NBLCK;
break;
case 'u':
lkmode = LK_UNLCK;
break;
default:
return luaL_error(L, "%s: invalid mode", funcname);
} }
if (!len) { if (!len) {
fseek (fh, 0L, SEEK_END); fseek (fh, 0L, SEEK_END);
@@ -389,17 +265,10 @@ static int _file_lock(lua_State * L, FILE * fh, const char *mode,
#else #else
struct flock f; struct flock f;
switch (*mode) { switch (*mode) {
case 'w': case 'w': f.l_type = F_WRLCK; break;
f.l_type = F_WRLCK; case 'r': f.l_type = F_RDLCK; break;
break; case 'u': f.l_type = F_UNLCK; break;
case 'r': default : return luaL_error (L, "%s: invalid mode", funcname);
f.l_type = F_RDLCK;
break;
case 'u':
f.l_type = F_UNLCK;
break;
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;
@@ -413,37 +282,35 @@ static int _file_lock(lua_State * L, FILE * fh, const char *mode,
typedef struct lfs_Lock { typedef struct lfs_Lock {
HANDLE fd; HANDLE fd;
} lfs_Lock; } lfs_Lock;
static int lfs_lock_dir(lua_State * L) static int lfs_lock_dir(lua_State *L) {
{ size_t pathl; HANDLE fd;
size_t pathl;
HANDLE fd;
lfs_Lock *lock; lfs_Lock *lock;
char *ln; char *ln;
const char *lockfile = "/lockfile.lfs"; const char *lockfile = "/lockfile.lfs";
const char *path = luaL_checklstring(L, 1, &pathl); const char *path = luaL_checklstring(L, 1, &pathl);
ln = (char*)malloc(pathl + strlen(lockfile) + 1); ln = (char*)malloc(pathl + strlen(lockfile) + 1);
if(!ln) { if(!ln) {
lua_pushnil(L); lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2;
lua_pushstring(L, strerror(errno)); }
strcpy(ln, path); strcat(ln, lockfile);
if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) {
int en = GetLastError();
free(ln); lua_pushnil(L);
if(en == ERROR_FILE_EXISTS || en == ERROR_SHARING_VIOLATION)
lua_pushstring(L, "File exists");
else
lua_pushstring(L, strerror(en));
return 2; return 2;
} }
strcpy(ln, path);
strcat(ln, lockfile);
fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
free(ln); free(ln);
if (fd == INVALID_HANDLE_VALUE) {
return lfs_win32_pusherror(L);
}
lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock));
lock->fd = fd; lock->fd = fd;
luaL_getmetatable (L, LOCK_METATABLE); luaL_getmetatable (L, LOCK_METATABLE);
lua_setmetatable (L, -2); lua_setmetatable (L, -2);
return 1; return 1;
} }
static int lfs_unlock_dir(lua_State *L) {
static int lfs_unlock_dir(lua_State * L)
{
lfs_Lock *lock = (lfs_Lock *)luaL_checkudata(L, 1, LOCK_METATABLE); lfs_Lock *lock = (lfs_Lock *)luaL_checkudata(L, 1, LOCK_METATABLE);
if(lock->fd != INVALID_HANDLE_VALUE) { if(lock->fd != INVALID_HANDLE_VALUE) {
CloseHandle(lock->fd); CloseHandle(lock->fd);
@@ -455,8 +322,7 @@ static int lfs_unlock_dir(lua_State * L)
typedef struct lfs_Lock { typedef struct lfs_Lock {
char *ln; char *ln;
} lfs_Lock; } lfs_Lock;
static int lfs_lock_dir(lua_State * L) static int lfs_lock_dir(lua_State *L) {
{
lfs_Lock *lock; lfs_Lock *lock;
size_t pathl; size_t pathl;
char *ln; char *ln;
@@ -465,26 +331,19 @@ static int lfs_lock_dir(lua_State * L)
lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock)); lock = (lfs_Lock*)lua_newuserdata(L, sizeof(lfs_Lock));
ln = (char*)malloc(pathl + strlen(lockfile) + 1); ln = (char*)malloc(pathl + strlen(lockfile) + 1);
if(!ln) { if(!ln) {
lua_pushnil(L); lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2;
lua_pushstring(L, strerror(errno));
return 2;
} }
strcpy(ln, path); strcpy(ln, path); strcat(ln, lockfile);
strcat(ln, lockfile);
if(symlink("lock", ln) == -1) { if(symlink("lock", ln) == -1) {
free(ln); free(ln); lua_pushnil(L);
lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2;
lua_pushstring(L, strerror(errno));
return 2;
} }
lock->ln = ln; lock->ln = ln;
luaL_getmetatable (L, LOCK_METATABLE); luaL_getmetatable (L, LOCK_METATABLE);
lua_setmetatable (L, -2); lua_setmetatable (L, -2);
return 1; return 1;
} }
static int lfs_unlock_dir(lua_State *L) {
static int lfs_unlock_dir(lua_State * L)
{
lfs_Lock *lock = (lfs_Lock *)luaL_checkudata(L, 1, LOCK_METATABLE); lfs_Lock *lock = (lfs_Lock *)luaL_checkudata(L, 1, LOCK_METATABLE);
if(lock->ln) { if(lock->ln) {
unlink(lock->ln); unlink(lock->ln);
@@ -495,8 +354,7 @@ static int lfs_unlock_dir(lua_State * L)
} }
#endif #endif
static int lfs_g_setmode(lua_State * L, FILE * f, int arg) static int lfs_g_setmode (lua_State *L, FILE *f, int arg) {
{
static const int mode[] = {_O_BINARY, _O_TEXT}; static const int mode[] = {_O_BINARY, _O_TEXT};
static const char *const modenames[] = {"binary", "text", NULL}; static const char *const modenames[] = {"binary", "text", NULL};
int op = luaL_checkoption(L, arg, NULL, modenames); int op = luaL_checkoption(L, arg, NULL, modenames);
@@ -517,8 +375,7 @@ static int lfs_g_setmode(lua_State * L, FILE * f, int arg)
} }
} }
static int lfs_f_setmode(lua_State * L) static int lfs_f_setmode(lua_State *L) {
{
return lfs_g_setmode(L, check_file(L, 1, "setmode"), 2); return lfs_g_setmode(L, check_file(L, 1, "setmode"), 2);
} }
@@ -529,8 +386,7 @@ static int lfs_f_setmode(lua_State * L)
** @param #3 Number with start position (optional). ** @param #3 Number with start position (optional).
** @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 = (long) luaL_optinteger (L, 3, 0); const long start = (long) luaL_optinteger (L, 3, 0);
@@ -552,8 +408,7 @@ static int file_lock(lua_State * L)
** @param #2 Number with start position (optional). ** @param #2 Number with start position (optional).
** @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 = (long) luaL_optinteger (L, 2, 0); const long start = (long) luaL_optinteger (L, 2, 0);
long len = (long) luaL_optinteger (L, 3, 0); long len = (long) luaL_optinteger (L, 3, 0);
@@ -574,40 +429,14 @@ 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
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);
#ifndef _WIN32 return pushresult(L, (lua_toboolean(L, 3) ? symlink : link)(oldpath, newpath), NULL);
return pushresult(L,
(lua_toboolean(L, 3) ? symlink : link) (oldpath,
newpath),
NULL);
#else #else
int symbolic = lua_toboolean(L, 3); errno = ENOSYS; /* = "Function not implemented" */
STAT_STRUCT oldpathinfo; return pushresult(L, -1, "make_link is not supported on Windows");
int is_dir = 0;
if (STAT_FUNC(oldpath, &oldpathinfo) == 0) {
is_dir = S_ISDIR(oldpathinfo.st_mode) != 0;
}
if (!symbolic && is_dir) {
lua_pushnil(L);
lua_pushstring(L,
"hard links to directories are not supported on Windows");
return 2;
}
int result = symbolic ? CreateSymbolicLink(newpath, oldpath, is_dir)
: CreateHardLink(newpath, oldpath, NULL);
if (result) {
return pushresult(L, result, NULL);
} else {
lua_pushnil(L);
lua_pushstring(L, symbolic ? "make_link CreateSymbolicLink() failed"
: "make_link CreateHardLink() failed");
return 2;
}
#endif #endif
} }
@@ -616,8 +445,7 @@ static int make_link(lua_State * L)
** Creates a directory. ** Creates a directory.
** @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); return pushresult(L, lfs_mkdir(path), NULL);
} }
@@ -627,8 +455,7 @@ static int make_dir(lua_State * L)
** Removes a directory. ** Removes a directory.
** @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); return pushresult(L, rmdir(path), NULL);
} }
@@ -637,8 +464,7 @@ static int remove_dir(lua_State * L)
/* /*
** Directory iterator ** Directory iterator
*/ */
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
@@ -685,8 +511,7 @@ 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) {
@@ -705,8 +530,7 @@ 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);
@@ -725,21 +549,14 @@ static int dir_iter_factory(lua_State * L)
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
#if LUA_VERSION_NUM >= 504
lua_pushnil(L);
lua_pushvalue(L, -2);
return 4;
#else
return 2; return 2;
#endif
} }
/* /*
** 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 */
@@ -753,11 +570,6 @@ static int dir_create_meta(lua_State * L)
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");
#if LUA_VERSION_NUM >= 504
lua_pushcfunction(L, dir_close);
lua_setfield(L, -2, "__close");
#endif
return 1; return 1;
} }
@@ -765,8 +577,7 @@ static int dir_create_meta(lua_State * L)
/* /*
** 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 */
@@ -782,15 +593,36 @@ static int lock_create_meta(lua_State * L)
} }
#ifdef _WIN32
#ifndef S_ISDIR
#define S_ISDIR(mode) (mode&_S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (mode&_S_IFREG)
#endif
#ifndef S_ISLNK
#define S_ISLNK(mode) (0)
#endif
#ifndef S_ISSOCK
#define S_ISSOCK(mode) (0)
#endif
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (0)
#endif
#ifndef S_ISCHR
#define S_ISCHR(mode) (mode&_S_IFCHR)
#endif
#ifndef S_ISBLK
#define S_ISBLK(mode) (0)
#endif
#endif
/* /*
** Convert the inode protection mode to a string. ** Convert the inode protection mode to a string.
*/ */
#ifdef _WIN32 #ifdef _WIN32
static const char *mode2string(unsigned short mode) static const char *mode2string (unsigned short mode) {
{
#else #else
static const char *mode2string(mode_t mode) static const char *mode2string (mode_t mode) {
{
#endif #endif
if ( S_ISREG(mode) ) if ( S_ISREG(mode) )
return "file"; return "file";
@@ -817,8 +649,7 @@ static const char *mode2string(mode_t mode)
** @param #2 Access time in seconds, current time is used if missing. ** @param #2 Access time in seconds, current time is used if missing.
** @param #3 Modification time in seconds, access 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;
@@ -835,81 +666,56 @@ static int file_utime(lua_State * L)
/* 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_pushinteger (L, (lua_Integer) info->st_dev); lua_pushinteger (L, (lua_Integer) 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_pushinteger (L, (lua_Integer) info->st_ino); lua_pushinteger (L, (lua_Integer) 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_pushinteger (L, (lua_Integer)info->st_nlink); lua_pushinteger (L, (lua_Integer)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_pushinteger (L, (lua_Integer)info->st_uid); lua_pushinteger (L, (lua_Integer)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_pushinteger (L, (lua_Integer)info->st_gid); lua_pushinteger (L, (lua_Integer)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_pushinteger (L, (lua_Integer) info->st_rdev); lua_pushinteger (L, (lua_Integer) 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_pushinteger (L, (lua_Integer) info->st_atime); lua_pushinteger (L, (lua_Integer) 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_pushinteger (L, (lua_Integer) info->st_mtime); lua_pushinteger (L, (lua_Integer) 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_pushinteger (L, (lua_Integer) info->st_ctime); lua_pushinteger (L, (lua_Integer) 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_pushinteger (L, (lua_Integer)info->st_size); lua_pushinteger (L, (lua_Integer)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_pushinteger (L, (lua_Integer)info->st_blocks); lua_pushinteger (L, (lua_Integer)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_pushinteger (L, (lua_Integer)info->st_blksize); lua_pushinteger (L, (lua_Integer)info->st_blksize);
} }
#endif #endif
@@ -919,61 +725,38 @@ static void push_st_blksize(lua_State * L, STAT_STRUCT * info)
*/ */
#ifdef _WIN32 #ifdef _WIN32
static const char *perm2string(unsigned short mode) static const char *perm2string (unsigned short mode) {
{
static char perms[10] = "---------"; static char perms[10] = "---------";
int i; int i;
for (i = 0; i < 9; i++) for (i=0;i<9;i++) perms[i]='-';
perms[i] = '-'; if (mode & _S_IREAD)
if (mode & _S_IREAD) { { perms[0] = 'r'; perms[3] = 'r'; perms[6] = 'r'; }
perms[0] = 'r'; if (mode & _S_IWRITE)
perms[3] = 'r'; { perms[1] = 'w'; perms[4] = 'w'; perms[7] = 'w'; }
perms[6] = 'r'; if (mode & _S_IEXEC)
} { perms[2] = 'x'; perms[5] = 'x'; perms[8] = 'x'; }
if (mode & _S_IWRITE) {
perms[1] = 'w';
perms[4] = 'w';
perms[7] = 'w';
}
if (mode & _S_IEXEC) {
perms[2] = 'x';
perms[5] = 'x';
perms[8] = 'x';
}
return perms; return perms;
} }
#else #else
static const char *perm2string(mode_t mode) static const char *perm2string (mode_t mode) {
{
static char perms[10] = "---------"; static char perms[10] = "---------";
int i; int i;
for (i = 0; i < 9; i++) for (i=0;i<9;i++) perms[i]='-';
perms[i] = '-'; if (mode & S_IRUSR) perms[0] = 'r';
if (mode & S_IRUSR) if (mode & S_IWUSR) perms[1] = 'w';
perms[0] = 'r'; if (mode & S_IXUSR) perms[2] = 'x';
if (mode & S_IWUSR) if (mode & S_IRGRP) perms[3] = 'r';
perms[1] = 'w'; if (mode & S_IWGRP) perms[4] = 'w';
if (mode & S_IXUSR) if (mode & S_IXGRP) perms[5] = 'x';
perms[2] = 'x'; if (mode & S_IROTH) perms[6] = 'r';
if (mode & S_IRGRP) if (mode & S_IWOTH) perms[7] = 'w';
perms[3] = 'r'; if (mode & S_IXOTH) perms[8] = 'x';
if (mode & S_IWGRP)
perms[4] = 'w';
if (mode & S_IXGRP)
perms[5] = 'x';
if (mode & S_IROTH)
perms[6] = 'r';
if (mode & S_IWOTH)
perms[7] = 'w';
if (mode & S_IXOTH)
perms[8] = 'x';
return perms; return perms;
} }
#endif #endif
/* permssions string */ /* permssions string */
static void push_st_perm(lua_State * L, STAT_STRUCT * info) static void push_st_perm (lua_State *L, STAT_STRUCT *info) {
{
lua_pushstring (L, perm2string (info->st_mode)); lua_pushstring (L, perm2string (info->st_mode));
} }
@@ -1007,17 +790,14 @@ struct _stat_members members[] = {
/* /*
** Get file or symbolic link information ** Get file or symbolic link information
*/ */
static int _file_info_(lua_State * L, static int _file_info_ (lua_State *L, int (*st)(const char*, STAT_STRUCT*)) {
int (*st)(const char *, STAT_STRUCT *))
{
STAT_STRUCT info; STAT_STRUCT info;
const char *file = luaL_checkstring (L, 1); const char *file = luaL_checkstring (L, 1);
int i; int i;
if (st(file, &info)) { if (st(file, &info)) {
lua_pushnil(L); lua_pushnil(L);
lua_pushfstring(L, "cannot obtain information from file '%s': %s", lua_pushfstring(L, "cannot obtain information from file '%s': %s", file, strerror(errno));
file, strerror(errno));
lua_pushinteger(L, errno); lua_pushinteger(L, errno);
return 3; return 3;
} }
@@ -1051,8 +831,7 @@ static int _file_info_(lua_State * L,
/* /*
** 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);
} }
@@ -1063,63 +842,39 @@ static int file_info(lua_State * L)
** Returns 1 if successful (with the target on top of the stack), ** Returns 1 if successful (with the target on top of the stack),
** 0 on failure (with stack unchanged, and errno set). ** 0 on failure (with stack unchanged, and errno set).
*/ */
static int push_link_target(lua_State * L) static int push_link_target(lua_State *L) {
{
const char *file = luaL_checkstring(L, 1);
#ifdef _WIN32 #ifdef _WIN32
HANDLE h = CreateFile(file, GENERIC_READ, errno = ENOSYS;
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, return 0;
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); #else
if (h == INVALID_HANDLE_VALUE) { const char *file = luaL_checkstring(L, 1);
return lfs_win32_pusherror(L);
}
#endif
char *target = NULL; char *target = NULL;
int tsize, size = 256; /* size = initial buffer capacity */ int tsize, size = 256; /* size = initial buffer capacity */
int ok = 0; while (1) {
while (!ok) { target = realloc(target, size);
char *target2 = realloc(target, size); if (!target) /* failed to allocate */
if (!target2) { /* failed to allocate */ return 0;
break;
}
target = target2;
#ifdef _WIN32
tsize = GetFinalPathNameByHandle(h, target, size, FILE_NAME_OPENED);
#else
tsize = readlink(file, target, size); tsize = readlink(file, target, size);
#endif
if (tsize < 0) { /* a readlink() error occurred */ if (tsize < 0) { /* a readlink() error occurred */
free(target);
return 0;
}
if (tsize < size)
break; break;
}
if (tsize < size) {
#ifdef _WIN32
if (tsize > 4 && strncmp(target, "\\\\?\\", 4) == 0) {
memmove_s(target, tsize - 3, target + 4, tsize - 3);
tsize -= 4;
}
#endif
ok = 1;
break;
}
/* possibly truncated readlink() result, double size and retry */ /* possibly truncated readlink() result, double size and retry */
size *= 2; size *= 2;
} }
if (ok) {
target[tsize] = '\0'; target[tsize] = '\0';
lua_pushlstring(L, target, tsize); lua_pushlstring(L, target, tsize);
}
#ifdef _WIN32
CloseHandle(h);
#endif
free(target); free(target);
return ok; return 1;
#endif
} }
/* /*
** 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) {
{
int ret; int ret;
if (lua_isstring (L, 2) && (strcmp(lua_tostring(L, 2), "target") == 0)) { if (lua_isstring (L, 2) && (strcmp(lua_tostring(L, 2), "target") == 0)) {
int ok = push_link_target(L); int ok = push_link_target(L);
@@ -1139,14 +894,10 @@ 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-2016 Kepler Project");
lua_pushliteral(L, "Copyright (C) 2003-2017 Kepler Project");
lua_setfield(L, -2, "_COPYRIGHT"); lua_setfield(L, -2, "_COPYRIGHT");
lua_pushliteral(L, 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");
"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");
lua_pushliteral(L, "LuaFileSystem " LFS_VERSION); lua_pushliteral(L, "LuaFileSystem " LFS_VERSION);
lua_setfield(L, -2, "_VERSION"); lua_setfield(L, -2, "_VERSION");
@@ -1170,13 +921,10 @@ static const struct luaL_Reg fslib[] = {
{NULL, NULL}, {NULL, NULL},
}; };
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_setglobal(L, LFS_LIBNAME);
set_info (L); set_info (L);
return 1; return 1;
} }

View File

@@ -1,4 +1,4 @@
LIBRARY lfs.dll LIBRARY lfs.dll
VERSION 1.8 VERSION 1.6
EXPORTS EXPORTS
luaopen_lfs luaopen_lfs

View File

@@ -1,7 +1,6 @@
/* /*
** LuaFileSystem ** LuaFileSystem
** Copyright Kepler Project 2003 - 2020 ** Copyright Kepler Project 2003 - 2016 (http://keplerproject.github.io/luafilesystem)
** (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

@@ -4,8 +4,6 @@ local tmp = "/tmp"
local sep = string.match (package.config, "[^\n]+") local sep = string.match (package.config, "[^\n]+")
local upper = ".." local upper = ".."
local is_unix = package.config:sub(1,1) == "/"
local lfs = require"lfs" local lfs = require"lfs"
print (lfs._VERSION) print (lfs._VERSION)
@@ -62,8 +60,6 @@ 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")
local data = "hello, file!"
f:write(data)
f:close() f:close()
io.write(".") io.write(".")
@@ -91,42 +87,16 @@ assert (new_att.modification == testdate1, "could not set modification time")
io.write(".") io.write(".")
io.flush() io.flush()
if lfs.link (tmpfile, "_a_link_for_test_", true) then -- Checking link (does not work on Windows)
local link_ok = lfs.link (tmpfile, "_a_link_for_test_", true)
if link_ok then
assert (link_ok == true, "successful lfs.link did not return true")
assert (lfs.attributes"_a_link_for_test_".mode == "file") 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_".mode == "link")
assert (lfs.symlinkattributes"_a_link_for_test_".target == tmpfile) assert (lfs.symlinkattributes"_a_link_for_test_".target == tmpfile)
assert (lfs.symlinkattributes("_a_link_for_test_", "target") == tmpfile) assert (lfs.symlinkattributes("_a_link_for_test_", "target") == tmpfile)
assert (lfs.symlinkattributes(tmpfile).mode == "file")
assert (lfs.link (tmpfile, "_a_hard_link_for_test_")) assert (lfs.link (tmpfile, "_a_hard_link_for_test_"))
assert (lfs.symlinkattributes"_a_hard_link_for_test_".mode == "file")
local fd = io.open(tmpfile)
assert(fd:read("*a") == data)
fd:close()
fd = io.open("_a_link_for_test_")
assert(fd:read("*a") == data)
fd:close()
fd = io.open("_a_hard_link_for_test_")
assert(fd:read("*a") == data)
fd:close()
fd = io.open("_a_hard_link_for_test_", "w+")
local data2 = "write in hard link"
fd:write(data2)
fd:close()
fd = io.open(tmpfile)
assert(fd:read("*a") == data2)
fd:close()
if is_unix then
assert (lfs.attributes (tmpfile, "nlink") == 2) assert (lfs.attributes (tmpfile, "nlink") == 2)
end
assert (os.remove"_a_link_for_test_") assert (os.remove"_a_link_for_test_")
assert (os.remove"_a_hard_link_for_test_") assert (os.remove"_a_hard_link_for_test_")
end end