commit 8addf14a396466982f62503a6dfa5793a53b1b8e Author: tomas Date: Tue Jul 27 14:15:24 2004 +0000 Initial revision diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7e0e577 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +# $Id: Makefile,v 1.1 2004/07/27 14:15:24 tomas Exp $ + +T= luafilesystem + +include ./config + +V= 1.0a +LIBNAME= lib$T.$V$(LIB_EXT) +L= $T.lua +TL= t_$T.lua + +SRCS= $T.c +OBJS= $T.o + + +lib: $(LIBNAME) + +$(LIBNAME): $(OBJS) $(TL) + $(CC) $(CFLAGS) $(LIB_OPTION) -o $(LIBNAME) $(OBJS) $(LIBS) + sed -e "s|LIB_NAME|$(LIB_DIR)/$(LIBNAME)|" $(TL) > $L + +$(LUA_DIR)/$L: $L + mkdir -p $(LUA_DIR) + cp $L $(LUA_DIR) + +install: $(LUA_DIR)/$L $(LIBNAME) + mkdir -p $(LIB_DIR) + cp $(LIBNAME) $(LIB_DIR) + +clean: + rm -f $L $(LIBNAME) $(OBJS) + +dist: + mkdir -p $(DIST_DIR) + cp config $(SRCS) $T.h $(TL) Makefile $(DIST_DIR) diff --git a/config b/config new file mode 100644 index 0000000..9cd88bc --- /dev/null +++ b/config @@ -0,0 +1,21 @@ +# Installation directories +# System's libraries directory (where Lua libraries are installed) +LIB_DIR= /usr/local/lib +LUA_DIR= /usr/local/lua + +# OS dependent +LIB_EXT= .dylib +#LIB_EXT= .so +LIB_OPTION= -dynamiclib #for MacOS X +#LIB_OPTION= -shared #for Linux + +# Compilation directives +# pre-compile and include mod2.lua into mod_lua.c +# On FreeBSD systems, the following line should be commented +DLLIB= -ldl +WARN= -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings +INCS= -I/usr/local/include/lua5 +LIBS= -L$(LIB_DIR) -llua -llualib -lm $(DLLIB) +CFLAGS= $(WARN) $(INCS) +CC= gcc + 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 @@ + + + +LuaFileSystem + + + + + +
+ +
+LuaFileSystem +
LuaFileSystem +
File system library for the +Lua +programming language +
+
+

+ +

+overview · +download · +manual · +credits · +contact us +
+

+ +


+

Contents

+

+

+ + +

Overview

+

+LuaFileSystem is a library developed to complement the set of functions +related to file systems offered by the standard Lua distribution. +One of its goals is to be as portable as Lua. +

+LuaFileSystem is free software and uses the same +license +as Lua 5.0. + + + +

Current version

+

+Current version is 1.0 alpha. +It was developed for Lua 5.0. +

+ + + +

Download

+

+LuaFileSystem can be downloaded in source code from the following links: +

+

+ + + +

What's new

+

+

+ + + +

Credits

+ +

+LuaFileSystem was designed by Roberto Ierusalimschy, +André Carregal and Tomás Guisasola as part of +The Kepler Project +which holds its copyright. +

+ + + +

Contact us

+ +

+For more information please +contact us. +Comments are welcome! +

+ + + +

+


+ +$Id: index.html,v 1.1 2004/07/27 14:15:24 tomas Exp $ + + + + + 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 @@ + + + +LuaFileSystem: license + + + + +
+

+License +

+ +LuaFileSystem +is free software: +it can be used for both academic and commercial purposes at absolutely no cost. +There are no royalties or GNU-like "copyleft" restrictions. +LuaFileSystem qualifies as +Open Source +software. +Its licenses are compatible with +GPL. +LuaFileSystem is not in the public domain and +The Kepler Project +keep its copyright. +The legal details are below. +

+ +The spirit of the license is that +you are free to use LuaFileSystem for any purpose at no cost without having to ask us. +The only requirement is that +if you do use LuaFileSystem, +then you should give us credit by including the appropriate copyright notice +somewhere in your product or its documentation. +

+ +The LuaFileSystem library is designed and implemented +by +Roberto Ierusalimschy, +André Carregal and +Tomás Guisasola. +The implementation is not derived from licensed software. +

+ + +


+Copyright © 2004 The Kepler Project. +

+ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +

+ +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +

+ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +

+ + +


+ +$Id: license.html,v 1.1 2004/07/27 14:15:24 tomas Exp $ + + + + 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 @@ + + + + +LuaFileSystem + + + + + +
+ +
+ +
+LuaFileSystem logo +
LuaFileSystem Reference Manual +
File system library for the +Lua +programming language +
+
+

+ +

+home · +introduction · +reference · +example +
+

+ +


+ + +

Introduction

+ +

+LuaFileSystem is a Lua library +developed to complement the set of functions related to file systems offered +by the standard Lua distribution. +

+LuaFileSystem is free software and uses the same +license +as Lua 5.0. +

+ + + +

Reference

+ +

+LuaFileSystem offers the following functions: +

+ + + +

Example

+ + + +

Contents

+

+

+

+ + +

+

+home · +introduction · +reference · +example +
+

+ +


+ +$Id: manual.html,v 1.1 2004/07/27 14:15:24 tomas Exp $ + + + + diff --git a/luafilesystem.c b/luafilesystem.c new file mode 100644 index 0000000..57167ea --- /dev/null +++ b/luafilesystem.c @@ -0,0 +1,351 @@ +/* +** File system manipulation library. +** This library offers these functions: +** luafilesystem.attributes (filepath [, attributename]) +** luafilesystem.chdir (path) +** luafilesystem.currentdir () +** luafilesystem.dir (path) +** luafilesystem.mkdir (path) +** luafilesystem.lock (fh, mode) +** luafilesystem.unlock (fh) +** +** $Id: luafilesystem.c,v 1.1 2004/07/27 14:15:24 tomas Exp $ +*/ + +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +#include +#include +#include + +#include "luafilesystem.h" + +/* Define 'strerror' for systems that do not implement it */ +#ifdef NO_STRERROR +#define strerror(_) "System unable to describe the error" +#endif + +/* Define 'getcwd' for systems that do not implement it */ +#ifdef NO_GETCWD +#define getcwd(p,s) NULL +#define getcwd_error "Function 'getcwd' not provided by system" +#else +#define getcwd_error strerror(errno) +#endif + +#define DIR_METATABLE "directory metatable" +#define MAX_DIR_LENGTH 1023 +#ifdef _WIN32 +typedef struct dir_data { + long hFile; + char pattern[MAX_DIR_LENGTH+1]; +} dir_data; +#endif + + +/* +** This function changes the working (current) directory +*/ +static int change_dir (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + if (chdir(path)) + luaL_error(L,"Unable to change working directory to '%s'\n%s\n", + path, chdir_error); + return 0; +} + +/* +** This function returns the current directory +** If unable to get the current directory, it returns nil +** and a string describing the error +*/ +static int get_dir (lua_State *L) { + char path[255+2]; + if (getcwd(path, 255) == NULL) { + lua_pushnil(L); + lua_pushstring(L, getcwd_error); + return 2; + } + else { + lua_pushstring(L, path); + return 1; + } +} + +/* +** 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) { + FILE **fh = (FILE **)luaL_checkudata (L, idx, "FILE*"); + if (fh == NULL) { + luaL_error (L, "%s: not a file", funcname); + return 0; + } else if (*fh == NULL) { + luaL_error (L, "%s: closed file", funcname); + return 0; + } else + return *fh; +} + + +/* +** +*/ +static int _file_lock (lua_State *L, FILE *fh, const char *mode, const long start, long len, const char *funcname) { + int code; +#ifdef WIN32 + /* lkmode valid values are: + _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. + _LK_NBLCK Locks the specified bytes. If the bytes cannot be locked, the constant returns an error. + _LK_NBRLCK Same as _LK_NBLCK. + _LK_RLCK Same as _LK_LOCK. + _LK_UNLCK Unlocks the specified bytes, which must have been previously locked. + + Regions should be locked only briefly and should be unlocked before closing a file or exiting the program. + + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__locking.asp + */ + int lkmode; + switch (*mode) { + case 'r': lkmode = _LK_NBLCK; break; + case 'w': lkmode = _LK_NBLCK; break; + case 'u': lkmode = _LK_UNLCK; break; + default : luaL_error (L, "%s: invalid mode", funcname); + } + if (!len) { + fseek (fh, 0L, SEEK_END); + len = ftell (fh); + } + fseek (fh, start, SEEK_SET); + code = _locking (fileno(fh), lkmode, len); +#else + struct flock f; + switch (*mode) { + case 'w': f.l_type = F_WRLCK; break; + case 'r': f.l_type = F_RDLCK; break; + case 'u': f.l_type = F_UNLCK; break; + default : luaL_error (L, "%s: invalid mode", funcname); + } + f.l_whence = SEEK_SET; + f.l_start = (off_t)start; + f.l_len = (off_t)len; + code = fcntl (fileno(fh), F_SETLK, &f); +#endif + return (code != -1); +} + + +/* +** Locks a file. +** @param #1 File handle. +** @param #2 String with lock mode ('w'rite, 'r'ead). +** @param #3 Number with start position (optional). +** @param #4 Number with length (optional). +*/ +static int file_lock (lua_State *L) { + FILE *fh = check_file (L, 1, "lock"); + const char *mode = luaL_checkstring (L, 2); + const long start = luaL_optlong (L, 3, 0); + long len = luaL_optlong (L, 4, 0); + if (_file_lock (L, fh, mode, start, len, "lock")) { + lua_pushboolean (L, 1); + return 1; + } else { + lua_pushboolean (L, 0); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } +} + + +/* +** Unlocks a file. +** @param #1 File handle. +** @param #2 Number with start position (optional). +** @param #3 Number with length (optional). +*/ +static int file_unlock (lua_State *L) { + FILE *fh = check_file (L, 1, "unlock"); + const long start = luaL_optlong (L, 2, 0); + long len = luaL_optlong (L, 3, 0); + if (_file_lock (L, fh, "u", start, len, "unlock")) { + lua_pushboolean (L, 1); + return 1; + } else { + lua_pushboolean (L, 0); + lua_pushfstring (L, "%s", strerror(errno)); + return 2; + } +} + + +/* +static void cgilua_sleep( lua_State *L ) +{ + unsigned int usec = (unsigned int)luaL_check_number( L, 1 ); + +#ifndef WIN32 + sleep( (unsigned int)ceil( usec/1000.0 )); +#else + Sleep( (DWORD)usec ); +#endif +} + +static void cgilua_filesize( lua_State *L ) +{ + struct stat info; + char *file = luaL_check_string( L, 1 ); + + if (stat(file, &info)) + { + lua_pushnil( L ); + lua_pushstring( L, "Cannot retrieve stat info from file" ); + return; + } + lua_pushnumber(L, info.st_size); +} +*/ + +static int make_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + int fail; +#ifdef WIN32 + int oldmask = umask (0); + fail = _mkdir (path); +#else + mode_t oldmask = umask( (mode_t)0 ); + fail = mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | + S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH ); +#endif + lua_pushboolean (L, fail); + umask (oldmask); + return 1; +} + + +/* +** Directory iterator +*/ +static int dir_iter (lua_State *L) { +#ifdef _WIN32 + dir_data *d = (dir_data *)lua_touserdata (L, lua_upvalueindex (1)); + struct _finddata_t c_file; + if (d->hFile == 0L) { /* first entry */ + if ((d->hFile = _findfirst (d->pattern, &c_file)) == -1L) { + lua_pushnil (L); + lua_pushstring (L, strerror (errno)); + return 2; + } else { + lua_pushstring (L, c_file.name); + return 1; + } + } else { /* next entry */ + if (_findnext (d->hFile, &c_file) == -1L) + return 0; + else { + lua_pushstring (L, c_file.name); + return 1; + } + } +#else + DIR *d = *(DIR **) lua_touserdata (L, lua_upvalueindex (1)); + struct dirent *entry; + if ((entry = readdir (d)) != NULL) { + lua_pushstring (L, entry->d_name); + return 1; + } + else + return 0; +#endif +} + + +/* +** Closes directory iterators +*/ +static int dir_close (lua_State *L) { +#ifdef _WIN32 + dir_data *d = (dir_data *)lua_touserdata (L, 1); + if (d->hFile) { + _findclose (d->hFile); + } +#else + DIR *d = *(DIR **)lua_touserdata (L, 1); + if (d) + closedir (d); +#endif + return 0; +} + + +/* +** Factory of directory iterators +*/ +static int dir_iter_factory (lua_State *L) { + const char *path = luaL_checkstring (L, 1); +#ifdef _WIN32 + dir_data *dir = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); + dir->hFile = 0L; + if (strlen(path) > MAX_DIR_LENGTH) + luaL_error (L, "path too long: %s", path); + else + sprintf (dir->pattern, "%s/*", path); + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); +#else + DIR **d = (DIR **) lua_newuserdata (L, sizeof(DIR *)); + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); + *d = opendir (path); + if (*d == NULL) + luaL_error (L, "cannot open %s: %s", path, strerror (errno)); +#endif + lua_pushcclosure (L, dir_iter, 1); + return 1; +} + + +/* +** Creates directory metatable. +*/ +static int dir_create_meta (lua_State *L) { + luaL_newmetatable (L, DIR_METATABLE); + /* set its __gc field */ + lua_pushstring (L, "__gc"); + lua_pushcfunction (L, dir_close); + lua_settable (L, -3); + + return 1; +} + + +static const struct luaL_reg fslib[] = { + {"chdir", change_dir}, + {"currentdir", get_dir}, + {"dir", dir_iter_factory}, + {"lock", file_lock}, + {"mkdir", make_dir}, + {"unlock", file_unlock}, + {NULL, NULL}, +}; + +int luaopen_luafilesystem (lua_State *L) { + dir_create_meta (L); + luaL_openlib (L, "luafilesystem", fslib, 0); + return 1; +} diff --git a/luafilesystem.def b/luafilesystem.def new file mode 100644 index 0000000..4cf9ec1 --- /dev/null +++ b/luafilesystem.def @@ -0,0 +1,5 @@ +LIBRARY luafilesystem.dll +DESCRIPTION "LuaFilesystem" +VERSION 1.0 +EXPORTS +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 @@ +/* Define 'chdir' for systems that do not implement it */ +/* $Id: luafilesystem.h,v 1.1 2004/07/27 14:15:24 tomas Exp $ */ +#ifdef NO_CHDIR +#define chdir(p) (-1) +#define chdir_error "Function 'chdir' not provided by system" +#else +#define chdir_error strerror(errno) +#endif + +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 @@ +-- $Id: t_luafilesystem.lua,v 1.1 2004/07/27 14:15:24 tomas Exp $ +if not luafilesystem and loadlib then + local libname = "LIB_NAME" + local libopen = "luaopen_luafilesystem" + local init, err1, err2 = loadlib (libname, libopen) + assert (init, (err1 or '')..(err2 or '')) + init () +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 @@ +#!/usr/local/bin/lua -i + +require"luafilesystem" + +print(luafilesystem.version) + +function p () + local fh = assert (io.open ("teste", 'r')) + assert (luafilesystem.lock (fh, 'r')) + print (fh:read"*a") + fh:close () +end + +function wr () + fh = assert (io.open ("teste", 'w')) + assert (luafilesystem.lock (fh, 'w')) +end + +function op () + fh = assert (io.open ("teste", 'r')) + assert (luafilesystem.lock (fh, 'r')) +end + +function fw (x) + assert (fh:write (x)) +end