diff options
| author | tomas <tomas> | 2004-07-27 14:15:24 +0000 |
|---|---|---|
| committer | tomas <tomas> | 2004-07-27 14:15:24 +0000 |
| commit | 8addf14a396466982f62503a6dfa5793a53b1b8e (patch) | |
| tree | 74d9db96683d623e3e789e2e51c7434da7ef6be4 | |
| download | luafilesystem-8addf14a396466982f62503a6dfa5793a53b1b8e.tar.gz luafilesystem-8addf14a396466982f62503a6dfa5793a53b1b8e.tar.bz2 luafilesystem-8addf14a396466982f62503a6dfa5793a53b1b8e.zip | |
Initial revision
| -rw-r--r-- | Makefile | 35 | ||||
| -rw-r--r-- | config | 21 | ||||
| -rw-r--r-- | doc/us/index.html | 114 | ||||
| -rw-r--r-- | doc/us/license.html | 78 | ||||
| -rw-r--r-- | doc/us/manual.html | 144 | ||||
| -rw-r--r-- | luafilesystem.c | 351 | ||||
| -rw-r--r-- | luafilesystem.def | 5 | ||||
| -rw-r--r-- | luafilesystem.h | 10 | ||||
| -rw-r--r-- | t_luafilesystem.lua | 8 | ||||
| -rw-r--r-- | teste.lua | 26 |
10 files changed, 792 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7e0e577 --- /dev/null +++ b/Makefile | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | # $Id: Makefile,v 1.1 2004/07/27 14:15:24 tomas Exp $ | ||
| 2 | |||
| 3 | T= luafilesystem | ||
| 4 | |||
| 5 | include ./config | ||
| 6 | |||
| 7 | V= 1.0a | ||
| 8 | LIBNAME= lib$T.$V$(LIB_EXT) | ||
| 9 | L= $T.lua | ||
| 10 | TL= t_$T.lua | ||
| 11 | |||
| 12 | SRCS= $T.c | ||
| 13 | OBJS= $T.o | ||
| 14 | |||
| 15 | |||
| 16 | lib: $(LIBNAME) | ||
| 17 | |||
| 18 | $(LIBNAME): $(OBJS) $(TL) | ||
| 19 | $(CC) $(CFLAGS) $(LIB_OPTION) -o $(LIBNAME) $(OBJS) $(LIBS) | ||
| 20 | sed -e "s|LIB_NAME|$(LIB_DIR)/$(LIBNAME)|" $(TL) > $L | ||
| 21 | |||
| 22 | $(LUA_DIR)/$L: $L | ||
| 23 | mkdir -p $(LUA_DIR) | ||
| 24 | cp $L $(LUA_DIR) | ||
| 25 | |||
| 26 | install: $(LUA_DIR)/$L $(LIBNAME) | ||
| 27 | mkdir -p $(LIB_DIR) | ||
| 28 | cp $(LIBNAME) $(LIB_DIR) | ||
| 29 | |||
| 30 | clean: | ||
| 31 | rm -f $L $(LIBNAME) $(OBJS) | ||
| 32 | |||
| 33 | dist: | ||
| 34 | mkdir -p $(DIST_DIR) | ||
| 35 | cp config $(SRCS) $T.h $(TL) Makefile $(DIST_DIR) | ||
| @@ -0,0 +1,21 @@ | |||
| 1 | # Installation directories | ||
| 2 | # System's libraries directory (where Lua libraries are installed) | ||
| 3 | LIB_DIR= /usr/local/lib | ||
| 4 | LUA_DIR= /usr/local/lua | ||
| 5 | |||
| 6 | # OS dependent | ||
| 7 | LIB_EXT= .dylib | ||
| 8 | #LIB_EXT= .so | ||
| 9 | LIB_OPTION= -dynamiclib #for MacOS X | ||
| 10 | #LIB_OPTION= -shared #for Linux | ||
| 11 | |||
| 12 | # Compilation directives | ||
| 13 | # pre-compile and include mod2.lua into mod_lua.c | ||
| 14 | # On FreeBSD systems, the following line should be commented | ||
| 15 | DLLIB= -ldl | ||
| 16 | WARN= -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings | ||
| 17 | INCS= -I/usr/local/include/lua5 | ||
| 18 | LIBS= -L$(LIB_DIR) -llua -llualib -lm $(DLLIB) | ||
| 19 | CFLAGS= $(WARN) $(INCS) | ||
| 20 | CC= gcc | ||
| 21 | |||
diff --git a/doc/us/index.html b/doc/us/index.html new file mode 100644 index 0000000..6b81ad9 --- /dev/null +++ b/doc/us/index.html | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | <html> | ||
| 2 | |||
| 3 | <head> | ||
| 4 | <title>LuaFileSystem</title> | ||
| 5 | <style type="text/css"> | ||
| 6 | ul { list-style-type: disc }; | ||
| 7 | </style> | ||
| 8 | </head> | ||
| 9 | |||
| 10 | <body bgcolor="#FFFFFF"> | ||
| 11 | |||
| 12 | <center> | ||
| 13 | <table border=0 cellspacing=2 cellpadding=2> | ||
| 14 | <tr><td align=center><a href="http://www.keplerproject.org"> | ||
| 15 | <img border=0 alt="LuaFileSystem" src="luafilesystem.png"></a> | ||
| 16 | <tr><td align=center><big><b>LuaFileSystem</b></big> | ||
| 17 | <tr><td align=center valign=top>File system library for the | ||
| 18 | <a href="http://www.lua.org">Lua</a> | ||
| 19 | programming language | ||
| 20 | </table> | ||
| 21 | </center> | ||
| 22 | <p> | ||
| 23 | |||
| 24 | <center><small> | ||
| 25 | <a href="#over">overview</a> · | ||
| 26 | <a href="#download">download</a> · | ||
| 27 | <a href="manual.html">manual</a> · | ||
| 28 | <a href="#credits">credits</a> · | ||
| 29 | <a href="#contact">contact us</a> | ||
| 30 | </small></center> | ||
| 31 | <p> | ||
| 32 | |||
| 33 | <hr> | ||
| 34 | <h2>Contents</h2> | ||
| 35 | <p> | ||
| 36 | <ul> | ||
| 37 | <li> <a href="#over">Overview</a> | ||
| 38 | <li> <a href="#version">Current Version</a> | ||
| 39 | <li> <a href="#download">Download</a> | ||
| 40 | <li> <a href="#manual">Manual</a> | ||
| 41 | <li> <a href="#credits">Credits</a> | ||
| 42 | <li> <a href="#contact">Contact us</a> | ||
| 43 | </ul> | ||
| 44 | |||
| 45 | <a name="over"></a> | ||
| 46 | <h2>Overview</h2> | ||
| 47 | <p> | ||
| 48 | LuaFileSystem is a library developed to complement the set of functions | ||
| 49 | related to file systems offered by the standard Lua distribution. | ||
| 50 | One of its goals is to be as portable as Lua. | ||
| 51 | <p> | ||
| 52 | LuaFileSystem is free software and uses the same | ||
| 53 | <a href="license.html">license</a> | ||
| 54 | as Lua 5.0. | ||
| 55 | |||
| 56 | |||
| 57 | <a name="version"></a> | ||
| 58 | <h2>Current version</h2> | ||
| 59 | <p> | ||
| 60 | Current version is 1.0 alpha. | ||
| 61 | It was developed for Lua 5.0. | ||
| 62 | </p> | ||
| 63 | |||
| 64 | |||
| 65 | <a name="download"></a> | ||
| 66 | <h2>Download</h2> | ||
| 67 | <p> | ||
| 68 | LuaFileSystem can be downloaded in source code from the following links: | ||
| 69 | <p> | ||
| 70 | <ul> | ||
| 71 | <li><a href="luafilesystem-1.0a.tar.gz">luafilesystem-1.0a.tar.gz</a>. | ||
| 72 | <li><a href="luafilesystem-1.0a.zip">luafilesystem-1.0a.zip</a>. | ||
| 73 | </ul> | ||
| 74 | |||
| 75 | |||
| 76 | <a name="new"></a> | ||
| 77 | <h2>What's new</h2> | ||
| 78 | <p> | ||
| 79 | <ul> | ||
| 80 | <li>[2/Aug/2004] Version 1.0 alpha released | ||
| 81 | </ul> | ||
| 82 | |||
| 83 | |||
| 84 | <a name="credits"></a> | ||
| 85 | <h2>Credits</h2> | ||
| 86 | |||
| 87 | <p> | ||
| 88 | LuaFileSystem was designed by Roberto Ierusalimschy, | ||
| 89 | André Carregal and Tomás Guisasola as part of | ||
| 90 | <a href="http://www.keplerproject.org">The Kepler Project</a> | ||
| 91 | which holds its copyright. | ||
| 92 | </p> | ||
| 93 | |||
| 94 | |||
| 95 | <a name="contact"></a> | ||
| 96 | <h2>Contact us</h2> | ||
| 97 | |||
| 98 | <p> | ||
| 99 | For more information please | ||
| 100 | <a href="mailto:tomas-NO-SPAM-THANKS@keplerproject.org">contact us</a>. | ||
| 101 | Comments are welcome! | ||
| 102 | </p> | ||
| 103 | |||
| 104 | |||
| 105 | |||
| 106 | <p> | ||
| 107 | <hr> | ||
| 108 | <small> | ||
| 109 | $Id: index.html,v 1.1 2004/07/27 14:15:24 tomas Exp $ | ||
| 110 | </small> | ||
| 111 | |||
| 112 | </body> | ||
| 113 | </html> | ||
| 114 | |||
diff --git a/doc/us/license.html b/doc/us/license.html new file mode 100644 index 0000000..f01eb86 --- /dev/null +++ b/doc/us/license.html | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | <! See Copyright Notice at the end of this file> | ||
| 2 | <HTML> | ||
| 3 | <HEAD> | ||
| 4 | <TITLE>LuaFileSystem: license</TITLE> | ||
| 5 | </HEAD> | ||
| 6 | |||
| 7 | <BODY BGCOLOR="#FFFFFF"> | ||
| 8 | |||
| 9 | <HR> | ||
| 10 | <H1> | ||
| 11 | License | ||
| 12 | </H1> | ||
| 13 | |||
| 14 | LuaFileSystem | ||
| 15 | is free software: | ||
| 16 | it can be used for both academic and commercial purposes at absolutely no cost. | ||
| 17 | There are no royalties or GNU-like "copyleft" restrictions. | ||
| 18 | LuaFileSystem qualifies as | ||
| 19 | <A HREF="http://www.opensource.org/docs/definition.html">Open Source</A> | ||
| 20 | software. | ||
| 21 | Its licenses are compatible with | ||
| 22 | <A HREF="http://www.gnu.org/licenses/gpl.html">GPL</A>. | ||
| 23 | LuaFileSystem is not in the public domain and | ||
| 24 | <a href="http://www.keplerproject.org">The Kepler Project</a> | ||
| 25 | keep its copyright. | ||
| 26 | The legal details are below. | ||
| 27 | <P> | ||
| 28 | |||
| 29 | The spirit of the license is that | ||
| 30 | you are free to use LuaFileSystem for any purpose at no cost without having to ask us. | ||
| 31 | The only requirement is that | ||
| 32 | if you do use LuaFileSystem, | ||
| 33 | then you should give us credit by including the appropriate copyright notice | ||
| 34 | somewhere in your product or its documentation. | ||
| 35 | <P> | ||
| 36 | |||
| 37 | The LuaFileSystem library is designed and implemented | ||
| 38 | by | ||
| 39 | Roberto Ierusalimschy, | ||
| 40 | André Carregal and | ||
| 41 | Tomás Guisasola. | ||
| 42 | The implementation is not derived from licensed software. | ||
| 43 | <P> | ||
| 44 | |||
| 45 | <!-- ===================================================================== --> | ||
| 46 | <HR> | ||
| 47 | Copyright © 2004 The Kepler Project. | ||
| 48 | <P> | ||
| 49 | |||
| 50 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 51 | of this software and associated documentation files (the "Software"), to deal | ||
| 52 | in the Software without restriction, including without limitation the rights | ||
| 53 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 54 | copies of the Software, and to permit persons to whom the Software is | ||
| 55 | furnished to do so, subject to the following conditions: | ||
| 56 | <P> | ||
| 57 | |||
| 58 | The above copyright notice and this permission notice shall be included in | ||
| 59 | all copies or substantial portions of the Software. | ||
| 60 | <P> | ||
| 61 | |||
| 62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 63 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 64 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 65 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 66 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 67 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 68 | THE SOFTWARE. | ||
| 69 | <P> | ||
| 70 | |||
| 71 | <!-- ===================================================================== --> | ||
| 72 | <HR> | ||
| 73 | <SMALL> | ||
| 74 | $Id: license.html,v 1.1 2004/07/27 14:15:24 tomas Exp $ | ||
| 75 | </SMALL> | ||
| 76 | |||
| 77 | </BODY> | ||
| 78 | </HTML> | ||
diff --git a/doc/us/manual.html b/doc/us/manual.html new file mode 100644 index 0000000..374d033 --- /dev/null +++ b/doc/us/manual.html | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | <! See Copyright Notice in license.html> | ||
| 2 | <html> | ||
| 3 | |||
| 4 | <head> | ||
| 5 | <title>LuaFileSystem</title> | ||
| 6 | <style type="text/css"> | ||
| 7 | ul { list-style-type: disc }; | ||
| 8 | </style> | ||
| 9 | </head> | ||
| 10 | |||
| 11 | <body bgcolor="#FFFFFF"> | ||
| 12 | |||
| 13 | <hr> | ||
| 14 | |||
| 15 | <center> | ||
| 16 | <table border=0 cellspacing=2 cellpadding=2> | ||
| 17 | <tr><td align=center><a href="http://www.keplerproject.org/luafilesystem"> | ||
| 18 | <img border=0 alt="LuaFileSystem logo" src="luafilesystem.png"></a> | ||
| 19 | <tr><td align=center><big><b>LuaFileSystem Reference Manual</b></big> | ||
| 20 | <tr><td align=center valign=top>File system library for the | ||
| 21 | <a href="http://www.lua.org">Lua</a> | ||
| 22 | programming language | ||
| 23 | </table> | ||
| 24 | </center> | ||
| 25 | <p> | ||
| 26 | |||
| 27 | <center><small> | ||
| 28 | <a href="index.html">home</a> · | ||
| 29 | <a href="#introduction">introduction</a> · | ||
| 30 | <a href="#reference">reference</a> · | ||
| 31 | <a href="#example">example</a> | ||
| 32 | </small></center> | ||
| 33 | <p> | ||
| 34 | |||
| 35 | <hr> | ||
| 36 | |||
| 37 | <a name="introduction"></a> | ||
| 38 | <h2>Introduction</h2> | ||
| 39 | |||
| 40 | <p> | ||
| 41 | LuaFileSystem is a <a href="http://www.lua.org">Lua</a> library | ||
| 42 | developed to complement the set of functions related to file systems offered | ||
| 43 | by the standard Lua distribution. | ||
| 44 | <p> | ||
| 45 | LuaFileSystem is free software and uses the same | ||
| 46 | <a href="license.html">license</a> | ||
| 47 | as Lua 5.0. | ||
| 48 | </p> | ||
| 49 | |||
| 50 | |||
| 51 | <a name="reference"></a> | ||
| 52 | <h2>Reference</h2> | ||
| 53 | |||
| 54 | <p> | ||
| 55 | LuaFileSystem offers the following functions: | ||
| 56 | <ul> | ||
| 57 | <a name="chdir"></a> | ||
| 58 | <li> <b><tt>luafilesystem.chdir (path)</tt></b> <br> | ||
| 59 | Changes the current | ||
| 60 | working directory to the given <tt>path</tt>. | ||
| 61 | |||
| 62 | <a name="getcwd"></a> | ||
| 63 | <li> <b><tt>luafilesystem.currentdir ()</tt></b> <br> | ||
| 64 | Returns the current | ||
| 65 | working directory or <code>nil</code> plus an error string. | ||
| 66 | |||
| 67 | <a name="dir"></a> | ||
| 68 | <li> <b><tt>luafilesystem.dir (path)</tt></b> <br> | ||
| 69 | Lua iterator over the entries | ||
| 70 | of a given directory. | ||
| 71 | |||
| 72 | <a name="lock"></a> | ||
| 73 | <li> <b><tt>luafilesystem.lock (filehandle, mode[, start[, length]])</tt></b> <br> | ||
| 74 | Locks a file or a part of it. | ||
| 75 | This function works on <em>open files</em>; | ||
| 76 | the file handle should be specified as the first argument. | ||
| 77 | The string <code>mode</code> could be either <code>r</code> (for a | ||
| 78 | read/shared lock) or <code>w</code> (for a write/exclusive lock). | ||
| 79 | The optional arguments <code>start</code> and <code>length</code> can be | ||
| 80 | used to specify a starting point and its length; | ||
| 81 | both should be numbers. | ||
| 82 | This function returns a boolean indicating if the operation was successful; | ||
| 83 | in case of error, it returns <code>false</code> plus a string describing the | ||
| 84 | error. | ||
| 85 | |||
| 86 | <a name="mkdir"></a> | ||
| 87 | <li> <b><tt>luafilesystem.mkdir (dirname)</tt></b> <br> | ||
| 88 | Creates a new directory. | ||
| 89 | The argument is the name of the new directory. | ||
| 90 | |||
| 91 | <a name="unlock"></a> | ||
| 92 | <li> <b><tt>luafilesystem.unlock (filehandle[, start[, length]])</tt></b> <br> | ||
| 93 | Unlocks a file or a part of it. | ||
| 94 | This function works on <em>open files</em>; | ||
| 95 | the file handle should be specified as the first argument. | ||
| 96 | The optional arguments <code>start</code> and <code>length</code> can be | ||
| 97 | used to specify a starting point and its length; | ||
| 98 | both should be numbers. | ||
| 99 | This function returns a boolean indicating if the operation was successful; | ||
| 100 | in case of error, it returns <code>false</code> plus a string describing the | ||
| 101 | error. | ||
| 102 | |||
| 103 | </ul> | ||
| 104 | |||
| 105 | |||
| 106 | <a name="example"></a> | ||
| 107 | <h2>Example</h2> | ||
| 108 | |||
| 109 | |||
| 110 | <a name="contents"></a> | ||
| 111 | <h2>Contents</h2> | ||
| 112 | <p> | ||
| 113 | <ul> | ||
| 114 | <li> <a href="#introduction">Introduction</a> | ||
| 115 | <li> <a href="#reference">Reference</a> | ||
| 116 | <ul> | ||
| 117 | <li> <a href="#chdir">chdir</a> | ||
| 118 | <li> <a href="#currentdir">currentdir</a> | ||
| 119 | <li> <a href="#dir">dir</a> | ||
| 120 | <li> <a href="#lock">lock</a> | ||
| 121 | <li> <a href="#mkdir">mkdir</a> | ||
| 122 | <li> <a href="#unlock">unlock</a> | ||
| 123 | </ul> | ||
| 124 | <li> <a href="#examples">Examples</a> | ||
| 125 | </ul> | ||
| 126 | </p> | ||
| 127 | |||
| 128 | |||
| 129 | <p> | ||
| 130 | <center><small> | ||
| 131 | <a href="index.html">home</a> · | ||
| 132 | <a href="#introduction">introduction</a> · | ||
| 133 | <a href="#reference">reference</a> · | ||
| 134 | <a href="#example">example</a> | ||
| 135 | </small></center> | ||
| 136 | <p> | ||
| 137 | |||
| 138 | <hr> | ||
| 139 | <small> | ||
| 140 | $Id: manual.html,v 1.1 2004/07/27 14:15:24 tomas Exp $ | ||
| 141 | </small> | ||
| 142 | |||
| 143 | </body> | ||
| 144 | </html> | ||
diff --git a/luafilesystem.c b/luafilesystem.c new file mode 100644 index 0000000..57167ea --- /dev/null +++ b/luafilesystem.c | |||
| @@ -0,0 +1,351 @@ | |||
| 1 | /* | ||
| 2 | ** File system manipulation library. | ||
| 3 | ** This library offers these functions: | ||
| 4 | ** luafilesystem.attributes (filepath [, attributename]) | ||
| 5 | ** luafilesystem.chdir (path) | ||
| 6 | ** luafilesystem.currentdir () | ||
| 7 | ** luafilesystem.dir (path) | ||
| 8 | ** luafilesystem.mkdir (path) | ||
| 9 | ** luafilesystem.lock (fh, mode) | ||
| 10 | ** luafilesystem.unlock (fh) | ||
| 11 | ** | ||
| 12 | ** $Id: luafilesystem.c,v 1.1 2004/07/27 14:15:24 tomas Exp $ | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <errno.h> | ||
| 16 | #include <stdio.h> | ||
| 17 | #include <string.h> | ||
| 18 | #include <time.h> | ||
| 19 | |||
| 20 | #ifdef WIN32 | ||
| 21 | #include <direct.h> | ||
| 22 | #include <io.h> | ||
| 23 | #include <sys/locking.h> | ||
| 24 | #else | ||
| 25 | #include <unistd.h> | ||
| 26 | #include <dirent.h> | ||
| 27 | #include <fcntl.h> | ||
| 28 | #include <sys/types.h> | ||
| 29 | #include <sys/stat.h> | ||
| 30 | #endif | ||
| 31 | |||
| 32 | #include <lua.h> | ||
| 33 | #include <lauxlib.h> | ||
| 34 | #include <lualib.h> | ||
| 35 | |||
| 36 | #include "luafilesystem.h" | ||
| 37 | |||
| 38 | /* Define 'strerror' for systems that do not implement it */ | ||
| 39 | #ifdef NO_STRERROR | ||
| 40 | #define strerror(_) "System unable to describe the error" | ||
| 41 | #endif | ||
| 42 | |||
| 43 | /* Define 'getcwd' for systems that do not implement it */ | ||
| 44 | #ifdef NO_GETCWD | ||
| 45 | #define getcwd(p,s) NULL | ||
| 46 | #define getcwd_error "Function 'getcwd' not provided by system" | ||
| 47 | #else | ||
| 48 | #define getcwd_error strerror(errno) | ||
| 49 | #endif | ||
| 50 | |||
| 51 | #define DIR_METATABLE "directory metatable" | ||
| 52 | #define MAX_DIR_LENGTH 1023 | ||
| 53 | #ifdef _WIN32 | ||
| 54 | typedef struct dir_data { | ||
| 55 | long hFile; | ||
| 56 | char pattern[MAX_DIR_LENGTH+1]; | ||
| 57 | } dir_data; | ||
| 58 | #endif | ||
| 59 | |||
| 60 | |||
| 61 | /* | ||
| 62 | ** This function changes the working (current) directory | ||
| 63 | */ | ||
| 64 | static int change_dir (lua_State *L) { | ||
| 65 | const char *path = luaL_checkstring(L, 1); | ||
| 66 | if (chdir(path)) | ||
| 67 | luaL_error(L,"Unable to change working directory to '%s'\n%s\n", | ||
| 68 | path, chdir_error); | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | ** This function returns the current directory | ||
| 74 | ** If unable to get the current directory, it returns nil | ||
| 75 | ** and a string describing the error | ||
| 76 | */ | ||
| 77 | static int get_dir (lua_State *L) { | ||
| 78 | char path[255+2]; | ||
| 79 | if (getcwd(path, 255) == NULL) { | ||
| 80 | lua_pushnil(L); | ||
| 81 | lua_pushstring(L, getcwd_error); | ||
| 82 | return 2; | ||
| 83 | } | ||
| 84 | else { | ||
| 85 | lua_pushstring(L, path); | ||
| 86 | return 1; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | /* | ||
| 91 | ** Check if the given element on the stack is a file and returns it. | ||
| 92 | */ | ||
| 93 | static FILE *check_file (lua_State *L, int idx, const char *funcname) { | ||
| 94 | FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*"); | ||
| 95 | if (fh == NULL) { | ||
| 96 | luaL_error (L, "%s: not a file", funcname); | ||
| 97 | return 0; | ||
| 98 | } else if (*fh == NULL) { | ||
| 99 | luaL_error (L, "%s: closed file", funcname); | ||
| 100 | return 0; | ||
| 101 | } else | ||
| 102 | return *fh; | ||
| 103 | } | ||
| 104 | |||
| 105 | |||
| 106 | /* | ||
| 107 | ** | ||
| 108 | */ | ||
| 109 | static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long start, long len, const char *funcname) { | ||
| 110 | int code; | ||
| 111 | #ifdef WIN32 | ||
| 112 | /* lkmode valid values are: | ||
| 113 | _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. | ||
| 114 | _LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error. | ||
| 115 | _LK_NBRLCK Same as _LK_NBLCK. | ||
| 116 | _LK_RLCK Same as _LK_LOCK. | ||
| 117 | _LK_UNLCK Unlocks the specified bytes, which must have been previously locked. | ||
| 118 | |||
| 119 | Regions should be locked only briefly and should be unlocked before closing a file or exiting the program. | ||
| 120 | |||
| 121 | http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp | ||
| 122 | */ | ||
| 123 | int lkmode; | ||
| 124 | switch (*mode) { | ||
| 125 | case 'r': lkmode = _LK_NBLCK; break; | ||
| 126 | case 'w': lkmode = _LK_NBLCK; break; | ||
| 127 | case 'u': lkmode = _LK_UNLCK; break; | ||
| 128 | default : luaL_error (L, "%s: invalid mode", funcname); | ||
| 129 | } | ||
| 130 | if (!len) { | ||
| 131 | fseek (fh, 0L, SEEK_END); | ||
| 132 | len = ftell (fh); | ||
| 133 | } | ||
| 134 | fseek (fh, start, SEEK_SET); | ||
| 135 | code = _locking (fileno(fh), lkmode, len); | ||
| 136 | #else | ||
| 137 | struct flock f; | ||
| 138 | switch (*mode) { | ||
| 139 | case 'w': f.l_type = F_WRLCK; break; | ||
| 140 | case 'r': f.l_type = F_RDLCK; break; | ||
| 141 | case 'u': f.l_type = F_UNLCK; break; | ||
| 142 | default : luaL_error (L, "%s: invalid mode", funcname); | ||
| 143 | } | ||
| 144 | f.l_whence = SEEK_SET; | ||
| 145 | f.l_start = (off_t)start; | ||
| 146 | f.l_len = (off_t)len; | ||
| 147 | code = fcntl (fileno(fh), F_SETLK, &f); | ||
| 148 | #endif | ||
| 149 | return (code != -1); | ||
| 150 | } | ||
| 151 | |||
| 152 | |||
| 153 | /* | ||
| 154 | ** Locks a file. | ||
| 155 | ** @param #1 File handle. | ||
| 156 | ** @param #2 String with lock mode ('w'rite, 'r'ead). | ||
| 157 | ** @param #3 Number with start position (optional). | ||
| 158 | ** @param #4 Number with length (optional). | ||
| 159 | */ | ||
| 160 | static int file_lock (lua_State *L) { | ||
| 161 | FILE *fh = check_file (L, 1, "lock"); | ||
| 162 | const char *mode = luaL_checkstring (L, 2); | ||
| 163 | const long start = luaL_optlong (L, 3, 0); | ||
| 164 | long len = luaL_optlong (L, 4, 0); | ||
| 165 | if (_file_lock (L, fh, mode, start, len, "lock")) { | ||
| 166 | lua_pushboolean (L, 1); | ||
| 167 | return 1; | ||
| 168 | } else { | ||
| 169 | lua_pushboolean (L, 0); | ||
| 170 | lua_pushfstring (L, "%s", strerror(errno)); | ||
| 171 | return 2; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | |||
| 176 | /* | ||
| 177 | ** Unlocks a file. | ||
| 178 | ** @param #1 File handle. | ||
| 179 | ** @param #2 Number with start position (optional). | ||
| 180 | ** @param #3 Number with length (optional). | ||
| 181 | */ | ||
| 182 | static int file_unlock (lua_State *L) { | ||
| 183 | FILE *fh = check_file (L, 1, "unlock"); | ||
| 184 | const long start = luaL_optlong (L, 2, 0); | ||
| 185 | long len = luaL_optlong (L, 3, 0); | ||
| 186 | if (_file_lock (L, fh, "u", start, len, "unlock")) { | ||
| 187 | lua_pushboolean (L, 1); | ||
| 188 | return 1; | ||
| 189 | } else { | ||
| 190 | lua_pushboolean (L, 0); | ||
| 191 | lua_pushfstring (L, "%s", strerror(errno)); | ||
| 192 | return 2; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | |||
| 197 | /* | ||
| 198 | static void cgilua_sleep( lua_State *L ) | ||
| 199 | { | ||
| 200 | unsigned int usec = (unsigned int)luaL_check_number( L, 1 ); | ||
| 201 | |||
| 202 | #ifndef WIN32 | ||
| 203 | sleep( (unsigned int)ceil( usec/1000.0 )); | ||
| 204 | #else | ||
| 205 | Sleep( (DWORD)usec ); | ||
| 206 | #endif | ||
| 207 | } | ||
| 208 | |||
| 209 | static void cgilua_filesize( lua_State *L ) | ||
| 210 | { | ||
| 211 | struct stat info; | ||
| 212 | char *file = luaL_check_string( L, 1 ); | ||
| 213 | |||
| 214 | if (stat(file, &info)) | ||
| 215 | { | ||
| 216 | lua_pushnil( L ); | ||
| 217 | lua_pushstring( L, "Cannot retrieve stat info from file" ); | ||
| 218 | return; | ||
| 219 | } | ||
| 220 | lua_pushnumber(L, info.st_size); | ||
| 221 | } | ||
| 222 | */ | ||
| 223 | |||
| 224 | static int make_dir (lua_State *L) { | ||
| 225 | const char *path = luaL_checkstring (L, 1); | ||
| 226 | int fail; | ||
| 227 | #ifdef WIN32 | ||
| 228 | int oldmask = umask (0); | ||
| 229 | fail = _mkdir (path); | ||
| 230 | #else | ||
| 231 | mode_t oldmask = umask( (mode_t)0 ); | ||
| 232 | fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | | ||
| 233 | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH ); | ||
| 234 | #endif | ||
| 235 | lua_pushboolean (L, fail); | ||
| 236 | umask (oldmask); | ||
| 237 | return 1; | ||
| 238 | } | ||
| 239 | |||
| 240 | |||
| 241 | /* | ||
| 242 | ** Directory iterator | ||
| 243 | */ | ||
| 244 | static int dir_iter (lua_State *L) { | ||
| 245 | #ifdef _WIN32 | ||
| 246 | dir_data *d = (dir_data *)lua_touserdata (L, lua_upvalueindex (1)); | ||
| 247 | struct _finddata_t c_file; | ||
| 248 | if (d->hFile == 0L) { /* first entry */ | ||
| 249 | if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { | ||
| 250 | lua_pushnil (L); | ||
| 251 | lua_pushstring (L, strerror (errno)); | ||
| 252 | return 2; | ||
| 253 | } else { | ||
| 254 | lua_pushstring (L, c_file.name); | ||
| 255 | return 1; | ||
| 256 | } | ||
| 257 | } else { /* next entry */ | ||
| 258 | if (_findnext (d->hFile, &c_file) == -1L) | ||
| 259 | return 0; | ||
| 260 | else { | ||
| 261 | lua_pushstring (L, c_file.name); | ||
| 262 | return 1; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | #else | ||
| 266 | DIR *d = *(DIR **) lua_touserdata (L, lua_upvalueindex (1)); | ||
| 267 | struct dirent *entry; | ||
| 268 | if ((entry = readdir (d)) != NULL) { | ||
| 269 | lua_pushstring (L, entry->d_name); | ||
| 270 | return 1; | ||
| 271 | } | ||
| 272 | else | ||
| 273 | return 0; | ||
| 274 | #endif | ||
| 275 | } | ||
| 276 | |||
| 277 | |||
| 278 | /* | ||
| 279 | ** Closes directory iterators | ||
| 280 | */ | ||
| 281 | static int dir_close (lua_State *L) { | ||
| 282 | #ifdef _WIN32 | ||
| 283 | dir_data *d = (dir_data *)lua_touserdata (L, 1); | ||
| 284 | if (d->hFile) { | ||
| 285 | _findclose (d->hFile); | ||
| 286 | } | ||
| 287 | #else | ||
| 288 | DIR *d = *(DIR **)lua_touserdata (L, 1); | ||
| 289 | if (d) | ||
| 290 | closedir (d); | ||
| 291 | #endif | ||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | |||
| 296 | /* | ||
| 297 | ** Factory of directory iterators | ||
| 298 | */ | ||
| 299 | static int dir_iter_factory (lua_State *L) { | ||
| 300 | const char *path = luaL_checkstring (L, 1); | ||
| 301 | #ifdef _WIN32 | ||
| 302 | dir_data *dir = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); | ||
| 303 | dir->hFile = 0L; | ||
| 304 | if (strlen(path) > MAX_DIR_LENGTH) | ||
| 305 | luaL_error (L, "path too long: %s", path); | ||
| 306 | else | ||
| 307 | sprintf (dir->pattern, "%s/*", path); | ||
| 308 | luaL_getmetatable (L, DIR_METATABLE); | ||
| 309 | lua_setmetatable (L, -2); | ||
| 310 | #else | ||
| 311 | DIR **d = (DIR **) lua_newuserdata (L, sizeof(DIR *)); | ||
| 312 | luaL_getmetatable (L, DIR_METATABLE); | ||
| 313 | lua_setmetatable (L, -2); | ||
| 314 | *d = opendir (path); | ||
| 315 | if (*d == NULL) | ||
| 316 | luaL_error (L, "cannot open %s: %s", path, strerror (errno)); | ||
| 317 | #endif | ||
| 318 | lua_pushcclosure (L, dir_iter, 1); | ||
| 319 | return 1; | ||
| 320 | } | ||
| 321 | |||
| 322 | |||
| 323 | /* | ||
| 324 | ** Creates directory metatable. | ||
| 325 | */ | ||
| 326 | static int dir_create_meta (lua_State *L) { | ||
| 327 | luaL_newmetatable (L, DIR_METATABLE); | ||
| 328 | /* set its __gc field */ | ||
| 329 | lua_pushstring (L, "__gc"); | ||
| 330 | lua_pushcfunction (L, dir_close); | ||
| 331 | lua_settable (L, -3); | ||
| 332 | |||
| 333 | return 1; | ||
| 334 | } | ||
| 335 | |||
| 336 | |||
| 337 | static const struct luaL_reg fslib[] = { | ||
| 338 | {"chdir", change_dir}, | ||
| 339 | {"currentdir", get_dir}, | ||
| 340 | {"dir", dir_iter_factory}, | ||
| 341 | {"lock", file_lock}, | ||
| 342 | {"mkdir", make_dir}, | ||
| 343 | {"unlock", file_unlock}, | ||
| 344 | {NULL, NULL}, | ||
| 345 | }; | ||
| 346 | |||
| 347 | int luaopen_luafilesystem (lua_State *L) { | ||
| 348 | dir_create_meta (L); | ||
| 349 | luaL_openlib (L, "luafilesystem", fslib, 0); | ||
| 350 | return 1; | ||
| 351 | } | ||
diff --git a/luafilesystem.def b/luafilesystem.def new file mode 100644 index 0000000..4cf9ec1 --- /dev/null +++ b/luafilesystem.def | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | LIBRARY luafilesystem.dll | ||
| 2 | DESCRIPTION "LuaFilesystem" | ||
| 3 | VERSION 1.0 | ||
| 4 | EXPORTS | ||
| 5 | luaopen_luafilesystem | ||
diff --git a/luafilesystem.h b/luafilesystem.h new file mode 100644 index 0000000..6178dd7 --- /dev/null +++ b/luafilesystem.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | /* Define 'chdir' for systems that do not implement it */ | ||
| 2 | /* $Id: luafilesystem.h,v 1.1 2004/07/27 14:15:24 tomas Exp $ */ | ||
| 3 | #ifdef NO_CHDIR | ||
| 4 | #define chdir(p) (-1) | ||
| 5 | #define chdir_error "Function 'chdir' not provided by system" | ||
| 6 | #else | ||
| 7 | #define chdir_error strerror(errno) | ||
| 8 | #endif | ||
| 9 | |||
| 10 | int luaopen_filesystem (lua_State *L); | ||
diff --git a/t_luafilesystem.lua b/t_luafilesystem.lua new file mode 100644 index 0000000..eb12afb --- /dev/null +++ b/t_luafilesystem.lua | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | -- $Id: t_luafilesystem.lua,v 1.1 2004/07/27 14:15:24 tomas Exp $ | ||
| 2 | if not luafilesystem and loadlib then | ||
| 3 | local libname = "LIB_NAME" | ||
| 4 | local libopen = "luaopen_luafilesystem" | ||
| 5 | local init, err1, err2 = loadlib (libname, libopen) | ||
| 6 | assert (init, (err1 or '')..(err2 or '')) | ||
| 7 | init () | ||
| 8 | end | ||
diff --git a/teste.lua b/teste.lua new file mode 100644 index 0000000..ec6da44 --- /dev/null +++ b/teste.lua | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #!/usr/local/bin/lua -i | ||
| 2 | |||
| 3 | require"luafilesystem" | ||
| 4 | |||
| 5 | print(luafilesystem.version) | ||
| 6 | |||
| 7 | function p () | ||
| 8 | local fh = assert (io.open ("teste", 'r')) | ||
| 9 | assert (luafilesystem.lock (fh, 'r')) | ||
| 10 | print (fh:read"*a") | ||
| 11 | fh:close () | ||
| 12 | end | ||
| 13 | |||
| 14 | function wr () | ||
| 15 | fh = assert (io.open ("teste", 'w')) | ||
| 16 | assert (luafilesystem.lock (fh, 'w')) | ||
| 17 | end | ||
| 18 | |||
| 19 | function op () | ||
| 20 | fh = assert (io.open ("teste", 'r')) | ||
| 21 | assert (luafilesystem.lock (fh, 'r')) | ||
| 22 | end | ||
| 23 | |||
| 24 | function fw (x) | ||
| 25 | assert (fh:write (x)) | ||
| 26 | end | ||
