Index: head/libexec/Makefile =================================================================== --- head/libexec/Makefile +++ head/libexec/Makefile @@ -8,6 +8,7 @@ ${_blacklistd-helper} \ ${_comsat} \ ${_dma} \ + flua \ getty \ ${_mail.local} \ ${_makewhatis.local} \ Index: head/libexec/flua/Makefile =================================================================== --- head/libexec/flua/Makefile +++ head/libexec/flua/Makefile @@ -0,0 +1,36 @@ +#! $FreeBSD$ + +.include + +LUASRC?= ${SRCTOP}/contrib/lua/src +.PATH: ${LUASRC} + +PROG= flua +WARNS?= 2 +MAN= # No manpage; this is internal. + +LIBADD= m + +# Core functions +SRCS= lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \ + lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \ + ltm.c lundump.c lvm.c lzio.c + +# Library functions; any change to these likely needs an accompanying change +# in our custom linit_flua.c. We use our custom linit.c to make it easier to +# support bootstrap flua that may not have supporting local libraries. +SRCS+= lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c \ + lmathlib.c loslib.c lstrlib.c ltablib.c lutf8lib.c loadlib.c + +# Entry point +SRCS+= lua.c + +# FreeBSD Extensions +.PATH: ${.CURDIR}/modules +SRCS+= linit_flua.c +SRCS+= lfs.c lposix.c + +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/modules -I${LUASRC} +CFLAGS+= -DLUA_PROGNAME="\"${PROG}\"" + +.include Index: head/libexec/flua/linit_flua.c =================================================================== --- head/libexec/flua/linit_flua.c +++ head/libexec/flua/linit_flua.c @@ -0,0 +1,73 @@ +/* $FreeBSD$ */ +/* +** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $ +** Initialization of libraries for lua.c and other clients +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +/* +** If you embed Lua in your program and need to open the standard +** libraries, call luaL_openlibs in your program. If you need a +** different set of libraries, copy this file to your project and edit +** it to suit your needs. +** +** You can also *preload* libraries, so that a later 'require' can +** open the library, which is already linked to the application. +** For that, do the following code: +** +** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); +** lua_pushcfunction(L, luaopen_modname); +** lua_setfield(L, -2, modname); +** lua_pop(L, 1); // remove PRELOAD table +*/ + +#include "lprefix.h" + + +#include + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" +#include "lfs.h" +#include "lposix.h" + +/* +** these libs are loaded by lua.c and are readily available to any Lua +** program +*/ +static const luaL_Reg loadedlibs[] = { + {"_G", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_UTF8LIBNAME, luaopen_utf8}, + {LUA_DBLIBNAME, luaopen_debug}, +#if defined(LUA_COMPAT_BITLIB) + {LUA_BITLIBNAME, luaopen_bit32}, +#endif + /* FreeBSD Extensions */ + {"lfs", luaopen_lfs}, + {"posix.unistd", luaopen_posix_unistd}, + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib; + /* "require" functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } +} + Index: head/libexec/flua/luaconf.h =================================================================== --- head/libexec/flua/luaconf.h +++ head/libexec/flua/luaconf.h @@ -0,0 +1,795 @@ +/* $FreeBSD$ */ +/* +** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef luaconf_h +#define luaconf_h + +#include +#include + + +/* +** =================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +** {==================================================================== +** System Configuration: macros to adapt (if needed) Lua to some +** particular platform, for instance compiling it with 32-bit numbers or +** restricting it to C89. +** ===================================================================== +*/ + +/* +@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You +** can also define LUA_32BITS in the make file, but changing here you +** ensure that all software connected to Lua will be compiled with the +** same configuration. +*/ +/* #define LUA_32BITS */ + + +/* +@@ LUA_USE_C89 controls the use of non-ISO-C89 features. +** Define it if you want Lua to avoid the use of a few C99 features +** or Windows-specific features on Windows. +*/ +/* #define LUA_USE_C89 */ + + +/* +** By default, Lua on Windows use (some) specific Windows features +*/ +#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_USE_WINDOWS /* enable goodies for regular Windows */ +#endif + + +#if defined(LUA_USE_WINDOWS) +#define LUA_DL_DLL /* enable support for DLL */ +#define LUA_USE_C89 /* broadly, Windows is C89 */ +#endif + + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ +#define LUA_USE_READLINE /* needs an extra library: -lreadline */ +#endif + +/* Local modifications: need io.popen */ +#ifdef __FreeBSD__ +#define LUA_USE_POSIX +#endif + +/* +@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for +** C89 ('long' and 'double'); Windows always has '__int64', so it does +** not need to use this case. +*/ +#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) +#define LUA_C89_NUMBERS +#endif + + + +/* +@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'. +*/ +/* avoid undefined shifts */ +#if ((INT_MAX >> 15) >> 15) >= 1 +#define LUAI_BITSINT 32 +#else +/* 'int' always must have at least 16 bits */ +#define LUAI_BITSINT 16 +#endif + + +/* +@@ LUA_INT_TYPE defines the type for Lua integers. +@@ LUA_FLOAT_TYPE defines the type for Lua floats. +** Lua should work fine with any mix of these options (if supported +** by your C compiler). The usual configurations are 64-bit integers +** and 'double' (the default), 32-bit integers and 'float' (for +** restricted platforms), and 'long'/'double' (for C compilers not +** compliant with C99, which may not have support for 'long long'). +*/ + +/* predefined options for LUA_INT_TYPE */ +#define LUA_INT_INT 1 +#define LUA_INT_LONG 2 +#define LUA_INT_LONGLONG 3 + +/* predefined options for LUA_FLOAT_TYPE */ +#define LUA_FLOAT_FLOAT 1 +#define LUA_FLOAT_DOUBLE 2 +#define LUA_FLOAT_LONGDOUBLE 3 + +#if defined(LUA_32BITS) /* { */ +/* +** 32-bit integers and 'float' +*/ +#if LUAI_BITSINT >= 32 /* use 'int' if big enough */ +#define LUA_INT_TYPE LUA_INT_INT +#else /* otherwise use 'long' */ +#define LUA_INT_TYPE LUA_INT_LONG +#endif +#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT + +#elif defined(LUA_C89_NUMBERS) /* }{ */ +/* +** largest types available for C89 ('long' and 'double') +*/ +#define LUA_INT_TYPE LUA_INT_LONG +#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE + +#endif /* } */ + + +/* +** default configuration for 64-bit Lua ('long long' and 'double') +*/ +#if !defined(LUA_INT_TYPE) +#define LUA_INT_TYPE LUA_INT_LONGLONG +#endif + +#if !defined(LUA_FLOAT_TYPE) +#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE +#endif + +/* }================================================================== */ + + + + +/* +** {================================================================== +** Configuration for Paths. +** =================================================================== +*/ + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +*/ +#define LUA_PATH_SEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXEC_DIR "!" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +** Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +** C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#if defined(_WIN32) /* { */ +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ + LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ + ".\\?.lua;" ".\\?\\init.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.dll;" \ + LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ + LUA_CDIR"loadall.dll;" ".\\?.dll" + +#else /* }{ */ + +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ + "./?.lua;" "./?/init.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif /* } */ + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Marks for exported symbols in the C code +** =================================================================== +*/ + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API +#define LUAMOD_API LUALIB_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +** exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables +** that are not to be exported to outside modules (LUAI_DDEF for +** definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#else /* }{ */ +#define LUAI_FUNC extern +#endif /* } */ + +#define LUAI_DDEC LUAI_FUNC +#define LUAI_DDEF /* empty */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2. +@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_5_2) /* { */ + +/* +@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated +** functions in the mathematical library. +*/ +#define LUA_COMPAT_MATHLIB + +/* +@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'. +*/ +#define LUA_COMPAT_BITLIB + +/* +@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod. +*/ +#define LUA_COMPAT_IPAIRS + +/* +@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for +** manipulating other integer types (lua_pushunsigned, lua_tounsigned, +** luaL_checkint, luaL_checklong, etc.) +*/ +#define LUA_COMPAT_APIINTCASTS + +#endif /* } */ + + +#if defined(LUA_COMPAT_5_1) /* { */ + +/* Incompatibilities from 5.2 -> 5.3 */ +#define LUA_COMPAT_MATHLIB +#define LUA_COMPAT_APIINTCASTS + +/* +@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. +** You can replace it with 'table.unpack'. +*/ +#define LUA_COMPAT_UNPACK + +/* +@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. +** You can replace it with 'package.searchers'. +*/ +#define LUA_COMPAT_LOADERS + +/* +@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. +** You can call your C function directly (with light C functions). +*/ +#define lua_cpcall(L,f,u) \ + (lua_pushcfunction(L, (f)), \ + lua_pushlightuserdata(L,(u)), \ + lua_pcall(L,1,0,0)) + + +/* +@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. +** You can rewrite 'log10(x)' as 'log(x, 10)'. +*/ +#define LUA_COMPAT_LOG10 + +/* +@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base +** library. You can rewrite 'loadstring(s)' as 'load(s)'. +*/ +#define LUA_COMPAT_LOADSTRING + +/* +@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. +*/ +#define LUA_COMPAT_MAXN + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +/* +@@ LUA_COMPAT_MODULE controls compatibility with previous +** module functions 'module' (Lua) and 'luaL_register' (C). +*/ +#define LUA_COMPAT_MODULE + +#endif /* } */ + + +/* +@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a +@@ a float mark ('.0'). +** This macro is not on by default even in compatibility mode, +** because this is not really an incompatibility. +*/ +/* #define LUA_COMPAT_FLOATSTRING */ + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Numbers. +** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* +** satisfy your needs. +** =================================================================== +*/ + +/* +@@ LUA_NUMBER is the floating-point type used by Lua. +@@ LUAI_UACNUMBER is the result of a 'default argument promotion' +@@ over a floating number. +@@ l_mathlim(x) corrects limit name 'x' to the proper float type +** by prefixing it with one of FLT/DBL/LDBL. +@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. +@@ LUA_NUMBER_FMT is the format for writing floats. +@@ lua_number2str converts a float to a string. +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations. +@@ l_floor takes the floor of a float. +@@ lua_str2number converts a decimal numeric string to a number. +*/ + + +/* The following definitions are good for most cases here */ + +#define l_floor(x) (l_mathop(floor)(x)) + +#define lua_number2str(s,sz,n) \ + l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) + +/* +@@ lua_numbertointeger converts a float number to an integer, or +** returns 0 if float is not within the range of a lua_Integer. +** (The range comparisons are tricky because of rounding. The tests +** here assume a two-complement representation, where MININTEGER always +** has an exact representation as a float; MAXINTEGER may not have one, +** and therefore its conversion to float may have an ill-defined value.) +*/ +#define lua_numbertointeger(n,p) \ + ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ + (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ + (*(p) = (LUA_INTEGER)(n), 1)) + + +/* now the variable definitions */ + +#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */ + +#define LUA_NUMBER float + +#define l_mathlim(n) (FLT_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.7g" + +#define l_mathop(op) op##f + +#define lua_str2number(s,p) strtof((s), (p)) + + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */ + +#define LUA_NUMBER long double + +#define l_mathlim(n) (LDBL_##n) + +#define LUAI_UACNUMBER long double + +#define LUA_NUMBER_FRMLEN "L" +#define LUA_NUMBER_FMT "%.19Lg" + +#define l_mathop(op) op##l + +#define lua_str2number(s,p) strtold((s), (p)) + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */ + +#define LUA_NUMBER double + +#define l_mathlim(n) (DBL_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.14g" + +#define l_mathop(op) op + +#define lua_str2number(s,p) strtod((s), (p)) + +#else /* }{ */ + +#error "numeric float type not defined" + +#endif /* } */ + + + +/* +@@ LUA_INTEGER is the integer type used by Lua. +** +@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. +** +@@ LUAI_UACINT is the result of a 'default argument promotion' +@@ over a lUA_INTEGER. +@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. +@@ LUA_INTEGER_FMT is the format for writing integers. +@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. +@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. +@@ lua_integer2str converts an integer to a string. +*/ + + +/* The following definitions are good for most cases here */ + +#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" + +#define LUAI_UACINT LUA_INTEGER + +#define lua_integer2str(s,sz,n) \ + l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n)) + +/* +** use LUAI_UACINT here to avoid problems with promotions (which +** can turn a comparison between unsigneds into a signed comparison) +*/ +#define LUA_UNSIGNED unsigned LUAI_UACINT + + +/* now the variable definitions */ + +#if LUA_INT_TYPE == LUA_INT_INT /* { int */ + +#define LUA_INTEGER int +#define LUA_INTEGER_FRMLEN "" + +#define LUA_MAXINTEGER INT_MAX +#define LUA_MININTEGER INT_MIN + +#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ + +#define LUA_INTEGER long +#define LUA_INTEGER_FRMLEN "l" + +#define LUA_MAXINTEGER LONG_MAX +#define LUA_MININTEGER LONG_MIN + +#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ + +/* use presence of macro LLONG_MAX as proxy for C99 compliance */ +#if defined(LLONG_MAX) /* { */ +/* use ISO C99 stuff */ + +#define LUA_INTEGER long long +#define LUA_INTEGER_FRMLEN "ll" + +#define LUA_MAXINTEGER LLONG_MAX +#define LUA_MININTEGER LLONG_MIN + +#elif defined(LUA_USE_WINDOWS) /* }{ */ +/* in Windows, can use specific Windows types */ + +#define LUA_INTEGER __int64 +#define LUA_INTEGER_FRMLEN "I64" + +#define LUA_MAXINTEGER _I64_MAX +#define LUA_MININTEGER _I64_MIN + +#else /* }{ */ + +#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ + or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)" + +#endif /* } */ + +#else /* }{ */ + +#error "numeric integer type not defined" + +#endif /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Dependencies with C99 and other C details +** =================================================================== +*/ + +/* +@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89. +** (All uses in Lua have only one format item.) +*/ +#if !defined(LUA_USE_C89) +#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i) +#else +#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i)) +#endif + + +/* +@@ lua_strx2number converts an hexadecimal numeric string to a number. +** In C99, 'strtod' does that conversion. Otherwise, you can +** leave 'lua_strx2number' undefined and Lua will provide its own +** implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_strx2number(s,p) lua_str2number(s,p) +#endif + + +/* +@@ lua_pointer2str converts a pointer to a readable string in a +** non-specified way. +*/ +#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p) + + +/* +@@ lua_number2strx converts a float to an hexadecimal numeric string. +** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. +** Otherwise, you can leave 'lua_number2strx' undefined and Lua will +** provide its own implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_number2strx(L,b,sz,f,n) \ + ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n))) +#endif + + +/* +** 'strtof' and 'opf' variants for math functions are not valid in +** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the +** availability of these variants. ('math.h' is already included in +** all files that use these macros.) +*/ +#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF)) +#undef l_mathop /* variants not available */ +#undef lua_str2number +#define l_mathop(op) (lua_Number)op /* no variant */ +#define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) +#endif + + +/* +@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation +** functions. It must be a numerical type; Lua will use 'intptr_t' if +** available, otherwise it will use 'ptrdiff_t' (the nearest thing to +** 'intptr_t' in C89) +*/ +#define LUA_KCONTEXT ptrdiff_t + +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(INTPTR_MAX) /* even in C99 this type is optional */ +#undef LUA_KCONTEXT +#define LUA_KCONTEXT intptr_t +#endif +#endif + + +/* +@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). +** Change that if you do not want to use C locales. (Code using this +** macro must include header 'locale.h'.) +*/ +#if !defined(lua_getlocaledecpoint) +#define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Language Variations +** ===================================================================== +*/ + +/* +@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some +** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from +** numbers to strings. Define LUA_NOCVTS2N to turn off automatic +** coercion from strings to numbers. +*/ +/* #define LUA_NOCVTN2S */ +/* #define LUA_NOCVTS2N */ + + +/* +@@ LUA_USE_APICHECK turns on several consistency checks on the C API. +** Define it as a help when debugging C code. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(l,e) assert(e) +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Macros that affect the API and must be stable (that is, must be the +** same when you compile Lua and when you compile code that links to +** Lua). You probably do not want/need to change them. +** ===================================================================== +*/ + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua from consuming unlimited stack +** space (and to reserve some numbers for pseudo-indices). +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + + +/* +@@ LUA_EXTRASPACE defines the size of a raw memory area associated with +** a Lua state with very fast access. +** CHANGE it if you need a different size. +*/ +#define LUA_EXTRASPACE (sizeof(void *)) + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@@ of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +** CHANGE it if it uses too much C-stack space. (For long double, +** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a +** smaller buffer would force a memory allocation for each call to +** 'string.format'.) +*/ +#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE +#define LUAL_BUFFERSIZE 8192 +#else +#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) +#endif + +/* }================================================================== */ + + +/* +@@ LUA_QL describes how error messages quote program elements. +** Lua does not use these macros anymore; they are here for +** compatibility only. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + + + +#endif + Index: head/libexec/flua/modules/lfs.h =================================================================== --- head/libexec/flua/modules/lfs.h +++ head/libexec/flua/modules/lfs.h @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2018 Conrad Meyer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#pragma once + +#include + +int luaopen_lfs(lua_State *L); Index: head/libexec/flua/modules/lfs.c =================================================================== --- head/libexec/flua/modules/lfs.c +++ head/libexec/flua/modules/lfs.c @@ -0,0 +1,424 @@ +/*- + * Copyright (c) 2018 Conrad Meyer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Portions derived from https://github.com/keplerproject/luafilesystem under + * the terms of the MIT license: + * + * Copyright (c) 2003-2014 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#ifndef _STANDALONE +#include +#include +#include +#include +#include +#include +#endif + +#include +#include "lauxlib.h" +#include "lfs.h" + +#ifdef _STANDALONE +#include "lstd.h" +#include "lutils.h" +#include "bootstrap.h" +#endif + +#ifndef nitems +#define nitems(x) (sizeof((x)) / sizeof((x)[0])) +#endif + +/* + * The goal is to emulate a subset of the upstream Lua FileSystem library, as + * faithfully as possible in the boot environment. Only APIs that seem useful + * need to emulated. + * + * Example usage: + * + * for file in lfs.dir("/boot") do + * print("\t"..file) + * end + * + * Prints: + * . + * .. + * (etc.) + * + * The other available API is lfs.attributes(), which functions somewhat like + * stat(2) and returns a table of values. Example code: + * + * attrs, errormsg, errorcode = lfs.attributes("/boot") + * if attrs == nil then + * print(errormsg) + * return errorcode + * end + * + * for k, v in pairs(attrs) do + * print(k .. ":\t" .. v) + * end + * return 0 + * + * Prints (on success): + * gid: 0 + * change: 140737488342640 + * mode: directory + * rdev: 0 + * ino: 4199275 + * dev: 140737488342544 + * modification: 140737488342576 + * size: 512 + * access: 140737488342560 + * permissions: 755 + * nlink: 58283552 + * uid: 1001 + */ + +#define DIR_METATABLE "directory iterator metatable" + +static int +lua_dir_iter_next(lua_State *L) +{ + struct dirent *entry; + DIR *dp, **dpp; + + dpp = (DIR **)luaL_checkudata(L, 1, DIR_METATABLE); + dp = *dpp; + luaL_argcheck(L, dp != NULL, 1, "closed directory"); + +#ifdef _STANDALONE + entry = readdirfd(dp->fd); +#else + entry = readdir(dp); +#endif + if (entry == NULL) { + closedir(dp); + *dpp = NULL; + return 0; + } + + lua_pushstring(L, entry->d_name); + return 1; +} + +static int +lua_dir_iter_close(lua_State *L) +{ + DIR *dp, **dpp; + + dpp = (DIR **)lua_touserdata(L, 1); + dp = *dpp; + if (dp == NULL) + return 0; + + closedir(dp); + *dpp = NULL; + return 0; +} + +static int +lua_dir(lua_State *L) +{ + const char *path; + DIR *dp; + + if (lua_gettop(L) != 1) { + lua_pushnil(L); + return 1; + } + + path = luaL_checkstring(L, 1); + dp = opendir(path); + if (dp == NULL) { + lua_pushnil(L); + return 1; + } + + lua_pushcfunction(L, lua_dir_iter_next); + *(DIR **)lua_newuserdata(L, sizeof(DIR **)) = dp; + luaL_getmetatable(L, DIR_METATABLE); + lua_setmetatable(L, -2); + return 2; +} + +static void +register_metatable(lua_State *L) +{ + /* + * Create so-called metatable for iterator object returned by + * lfs.dir(). + */ + luaL_newmetatable(L, DIR_METATABLE); + + lua_newtable(L); + lua_pushcfunction(L, lua_dir_iter_next); + lua_setfield(L, -2, "next"); + lua_pushcfunction(L, lua_dir_iter_close); + lua_setfield(L, -2, "close"); + + /* Magically associate anonymous method table with metatable. */ + lua_setfield(L, -2, "__index"); + /* Implement magic destructor method */ + lua_pushcfunction(L, lua_dir_iter_close); + lua_setfield(L, -2, "__gc"); + + lua_pop(L, 1); +} + +#define PUSH_INTEGER(lname, stname) \ +static void \ +push_st_ ## lname (lua_State *L, struct stat *sb) \ +{ \ + lua_pushinteger(L, (lua_Integer)sb->st_ ## stname); \ +} +PUSH_INTEGER(dev, dev) +PUSH_INTEGER(ino, ino) +PUSH_INTEGER(nlink, nlink) +PUSH_INTEGER(uid, uid) +PUSH_INTEGER(gid, gid) +PUSH_INTEGER(rdev, rdev) +PUSH_INTEGER(access, atime) +PUSH_INTEGER(modification, mtime) +PUSH_INTEGER(change, ctime) +PUSH_INTEGER(size, size) +#undef PUSH_INTEGER + +static void +push_st_mode(lua_State *L, struct stat *sb) +{ + const char *mode_s; + mode_t mode; + + mode = (sb->st_mode & S_IFMT); + if (S_ISREG(mode)) + mode_s = "file"; + else if (S_ISDIR(mode)) + mode_s = "directory"; + else if (S_ISLNK(mode)) + mode_s = "link"; + else if (S_ISSOCK(mode)) + mode_s = "socket"; + else if (S_ISFIFO(mode)) + mode_s = "fifo"; + else if (S_ISCHR(mode)) + mode_s = "char device"; + else if (S_ISBLK(mode)) + mode_s = "block device"; + else + mode_s = "other"; + + lua_pushstring(L, mode_s); +} + +static void +push_st_permissions(lua_State *L, struct stat *sb) +{ + char buf[20]; + + /* + * XXX + * Could actually format as "-rwxrwxrwx" -- do we care? + */ + snprintf(buf, sizeof(buf), "%o", sb->st_mode & ~S_IFMT); + lua_pushstring(L, buf); +} + +#define PUSH_ENTRY(n) { #n, push_st_ ## n } +struct stat_members { + const char *name; + void (*push)(lua_State *, struct stat *); +} members[] = { + PUSH_ENTRY(mode), + PUSH_ENTRY(dev), + PUSH_ENTRY(ino), + PUSH_ENTRY(nlink), + PUSH_ENTRY(uid), + PUSH_ENTRY(gid), + PUSH_ENTRY(rdev), + PUSH_ENTRY(access), + PUSH_ENTRY(modification), + PUSH_ENTRY(change), + PUSH_ENTRY(size), + PUSH_ENTRY(permissions), +}; +#undef PUSH_ENTRY + +static int +lua_attributes(lua_State *L) +{ + struct stat sb; + const char *path, *member; + size_t i; + int rc; + + path = luaL_checkstring(L, 1); + if (path == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "cannot convert first argument to string"); + lua_pushinteger(L, EINVAL); + return 3; + } + + rc = stat(path, &sb); + if (rc != 0) { + lua_pushnil(L); + lua_pushfstring(L, + "cannot obtain information from file '%s': %s", path, + strerror(errno)); + lua_pushinteger(L, errno); + return 3; + } + + if (lua_isstring(L, 2)) { + member = lua_tostring(L, 2); + for (i = 0; i < nitems(members); i++) { + if (strcmp(members[i].name, member) != 0) + continue; + + members[i].push(L, &sb); + return 1; + } + return luaL_error(L, "invalid attribute name '%s'", member); + } + + /* Create or reuse existing table */ + lua_settop(L, 2); + if (!lua_istable(L, 2)) + lua_newtable(L); + + /* Export all stat data to caller */ + for (i = 0; i < nitems(members); i++) { + lua_pushstring(L, members[i].name); + members[i].push(L, &sb); + lua_rawset(L, -3); + } + return 1; +} + +#ifndef _STANDALONE +#define lfs_mkdir_impl(path) (mkdir((path), \ + S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | \ + S_IROTH | S_IXOTH)) + +static int +lua_mkdir(lua_State *L) +{ + const char *path; + int error, serrno; + + path = luaL_checkstring(L, 1); + if (path == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "cannot convert first argument to string"); + lua_pushinteger(L, EINVAL); + return 3; + } + + error = lfs_mkdir_impl(path); + if (error == -1) { + /* Save it; unclear what other libc functions may be invoked */ + serrno = errno; + lua_pushnil(L); + lua_pushfstring(L, strerror(serrno)); + lua_pushinteger(L, serrno); + return 3; + } + + lua_pushboolean(L, 1); + return 1; +} + +static int +lua_rmdir(lua_State *L) +{ + const char *path; + int error, serrno; + + path = luaL_checkstring(L, 1); + if (path == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "cannot convert first argument to string"); + lua_pushinteger(L, EINVAL); + return 3; + } + + error = rmdir(path); + if (error == -1) { + /* Save it; unclear what other libc functions may be invoked */ + serrno = errno; + lua_pushnil(L); + lua_pushfstring(L, strerror(serrno)); + lua_pushinteger(L, serrno); + return 3; + } + + lua_pushboolean(L, 1); + return 1; +} +#endif + +#define REG_SIMPLE(n) { #n, lua_ ## n } +static const struct luaL_Reg fslib[] = { + REG_SIMPLE(attributes), + REG_SIMPLE(dir), +#ifndef _STANDALONE + REG_SIMPLE(mkdir), + REG_SIMPLE(rmdir), +#endif + { NULL, NULL }, +}; +#undef REG_SIMPLE + +int +luaopen_lfs(lua_State *L) +{ + register_metatable(L); + luaL_newlib(L, fslib); + return 1; +} Index: head/libexec/flua/modules/lposix.h =================================================================== --- head/libexec/flua/modules/lposix.h +++ head/libexec/flua/modules/lposix.h @@ -0,0 +1,11 @@ +/*- + * + * This file is in the public domain. + */ +/* $FreeBSD$ */ + +#pragma once + +#include + +int luaopen_posix_unistd(lua_State *L); Index: head/libexec/flua/modules/lposix.c =================================================================== --- head/libexec/flua/modules/lposix.c +++ head/libexec/flua/modules/lposix.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2019 Kyle Evans + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include "lauxlib.h" +#include "lposix.h" + +/* + * Minimal implementation of luaposix needed for internal FreeBSD bits. + */ + +static int +lua_getpid(lua_State *L) +{ + int n; + + n = lua_gettop(L); + luaL_argcheck(L, n == 0, 1, "too many arguments"); + lua_pushinteger(L, getpid()); + return 1; +} + +#define REG_SIMPLE(n) { #n, lua_ ## n } +static const struct luaL_Reg unistdlib[] = { + REG_SIMPLE(getpid), + { NULL, NULL }, +}; +#undef REG_SIMPLE + +int +luaopen_posix_unistd(lua_State *L) +{ + luaL_newlib(L, unistdlib); + return 1; +} Index: head/share/mk/src.lua.mk =================================================================== --- head/share/mk/src.lua.mk +++ head/share/mk/src.lua.mk @@ -0,0 +1,45 @@ +# $FreeBSD$ +# +# Lua helper file for FreeBSD /usr/src builds. +# +# This file provides any necessary assistance for consumers of Lua in the base +# system. + +.if !target(____) +____: + +.include + +# +# LUA_INSTALL_PATH and LUA_CMD describe where the internal lua has been +# installed to, along with the name of the internal command. The default +# name is flua. +# +# LUA_CMD can be overwritten to point to a Lua that isn't flua. This is fine, +# but parts of the src build that use it may have certain expectations that +# may only be fulfilled by the in-tree Lua. The user overwriting it is expected +# to understand these and provide the expectations. +# +# flua is currently equivalent to Lua 5.3, with the following modules: +# - luafilesystem +# - lua-posix +# +LUA_INSTALL_PATH?= ${LIBEXECDIR} +LUA_CMD?= flua + +# +# Some standalone usage may want a variable that tries to find the lua command, +# and cannot necessarily embed the logic for trying to find it amongst bootstrap +# tools. For these, we provide the LUA variable. +# +# The LUA variable should point to LUA_CMD on the system, if it exists. +# Otherwise, consumers will have to settle for a PATH search and PATH being +# appropriately set. +# +.if !defined(LUA) && exists(${LUA_INSTALL_PATH}/${LUA_CMD}) +LUA= ${LUA_INSTALL_PATH}/${LUA_CMD} +.else +LUA?= ${LUA_CMD} +.endif + +.endif # !target(____) Index: head/stand/defs.mk =================================================================== --- head/stand/defs.mk +++ head/stand/defs.mk @@ -42,6 +42,7 @@ # LUAPATH is where we search for and install lua scripts. LUAPATH?= /boot/lua +FLUASRC?= ${SRCTOP}/libexec/flua LIBSA= ${BOOTOBJ}/libsa/libsa.a .if ${MACHINE} == "i386" Index: head/stand/liblua/Makefile =================================================================== --- head/stand/liblua/Makefile +++ head/stand/liblua/Makefile @@ -23,7 +23,10 @@ #SRCS+= lbitlib.c liolib.c lmathlib.c loslib.c ltablib.c # Our utilities. -SRCS+= lerrno.c lfs.c lstd.c lutils.c +SRCS+= lerrno.c lstd.c lutils.c + +.PATH: ${FLUASRC}/modules +SRCS+= lfs.c WARNS= 3 Index: head/stand/liblua/lfs.h =================================================================== --- head/stand/liblua/lfs.h +++ head/stand/liblua/lfs.h @@ -1,33 +0,0 @@ -/*- - * Copyright (c) 2018 Conrad Meyer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#pragma once - -#include - -int luaopen_lfs(lua_State *L); Index: head/stand/liblua/lfs.c =================================================================== --- head/stand/liblua/lfs.c +++ head/stand/liblua/lfs.c @@ -1,342 +0,0 @@ -/*- - * Copyright (c) 2018 Conrad Meyer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Portions derived from https://github.com/keplerproject/luafilesystem under - * the terms of the MIT license: - * - * Copyright (c) 2003-2014 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. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include "lauxlib.h" -#include "lfs.h" -#include "lstd.h" -#include "lutils.h" -#include "bootstrap.h" - -#ifndef nitems -#define nitems(x) (sizeof((x)) / sizeof((x)[0])) -#endif - -/* - * The goal is to emulate a subset of the upstream Lua FileSystem library, as - * faithfully as possible in the boot environment. Only APIs that seem useful - * need to emulated. - * - * Example usage: - * - * for file in lfs.dir("/boot") do - * print("\t"..file) - * end - * - * Prints: - * . - * .. - * (etc.) - * - * The other available API is lfs.attributes(), which functions somewhat like - * stat(2) and returns a table of values. Example code: - * - * attrs, errormsg, errorcode = lfs.attributes("/boot") - * if attrs == nil then - * print(errormsg) - * return errorcode - * end - * - * for k, v in pairs(attrs) do - * print(k .. ":\t" .. v) - * end - * return 0 - * - * Prints (on success): - * gid: 0 - * change: 140737488342640 - * mode: directory - * rdev: 0 - * ino: 4199275 - * dev: 140737488342544 - * modification: 140737488342576 - * size: 512 - * access: 140737488342560 - * permissions: 755 - * nlink: 58283552 - * uid: 1001 - */ - -#define DIR_METATABLE "directory iterator metatable" - -static int -lua_dir_iter_next(lua_State *L) -{ - struct dirent *entry; - DIR *dp, **dpp; - - dpp = (DIR **)luaL_checkudata(L, 1, DIR_METATABLE); - dp = *dpp; - luaL_argcheck(L, dp != NULL, 1, "closed directory"); - - entry = readdirfd(dp->fd); - if (entry == NULL) { - closedir(dp); - *dpp = NULL; - return 0; - } - - lua_pushstring(L, entry->d_name); - return 1; -} - -static int -lua_dir_iter_close(lua_State *L) -{ - DIR *dp, **dpp; - - dpp = (DIR **)lua_touserdata(L, 1); - dp = *dpp; - if (dp == NULL) - return 0; - - closedir(dp); - *dpp = NULL; - return 0; -} - -static int -lua_dir(lua_State *L) -{ - const char *path; - DIR *dp; - - if (lua_gettop(L) != 1) { - lua_pushnil(L); - return 1; - } - - path = luaL_checkstring(L, 1); - dp = opendir(path); - if (dp == NULL) { - lua_pushnil(L); - return 1; - } - - lua_pushcfunction(L, lua_dir_iter_next); - *(DIR **)lua_newuserdata(L, sizeof(DIR **)) = dp; - luaL_getmetatable(L, DIR_METATABLE); - lua_setmetatable(L, -2); - return 2; -} - -static void -register_metatable(lua_State *L) -{ - /* - * Create so-called metatable for iterator object returned by - * lfs.dir(). - */ - luaL_newmetatable(L, DIR_METATABLE); - - lua_newtable(L); - lua_pushcfunction(L, lua_dir_iter_next); - lua_setfield(L, -2, "next"); - lua_pushcfunction(L, lua_dir_iter_close); - lua_setfield(L, -2, "close"); - - /* Magically associate anonymous method table with metatable. */ - lua_setfield(L, -2, "__index"); - /* Implement magic destructor method */ - lua_pushcfunction(L, lua_dir_iter_close); - lua_setfield(L, -2, "__gc"); - - lua_pop(L, 1); -} - -#define PUSH_INTEGER(lname, stname) \ -static void \ -push_st_ ## lname (lua_State *L, struct stat *sb) \ -{ \ - lua_pushinteger(L, (lua_Integer)sb->st_ ## stname); \ -} -PUSH_INTEGER(dev, dev) -PUSH_INTEGER(ino, ino) -PUSH_INTEGER(nlink, nlink) -PUSH_INTEGER(uid, uid) -PUSH_INTEGER(gid, gid) -PUSH_INTEGER(rdev, rdev) -PUSH_INTEGER(access, atime) -PUSH_INTEGER(modification, mtime) -PUSH_INTEGER(change, ctime) -PUSH_INTEGER(size, size) -#undef PUSH_INTEGER - -static void -push_st_mode(lua_State *L, struct stat *sb) -{ - const char *mode_s; - mode_t mode; - - mode = (sb->st_mode & S_IFMT); - if (S_ISREG(mode)) - mode_s = "file"; - else if (S_ISDIR(mode)) - mode_s = "directory"; - else if (S_ISLNK(mode)) - mode_s = "link"; - else if (S_ISSOCK(mode)) - mode_s = "socket"; - else if (S_ISFIFO(mode)) - mode_s = "fifo"; - else if (S_ISCHR(mode)) - mode_s = "char device"; - else if (S_ISBLK(mode)) - mode_s = "block device"; - else - mode_s = "other"; - - lua_pushstring(L, mode_s); -} - -static void -push_st_permissions(lua_State *L, struct stat *sb) -{ - char buf[20]; - - /* - * XXX - * Could actually format as "-rwxrwxrwx" -- do we care? - */ - snprintf(buf, sizeof(buf), "%o", sb->st_mode & ~S_IFMT); - lua_pushstring(L, buf); -} - -#define PUSH_ENTRY(n) { #n, push_st_ ## n } -struct stat_members { - const char *name; - void (*push)(lua_State *, struct stat *); -} members[] = { - PUSH_ENTRY(mode), - PUSH_ENTRY(dev), - PUSH_ENTRY(ino), - PUSH_ENTRY(nlink), - PUSH_ENTRY(uid), - PUSH_ENTRY(gid), - PUSH_ENTRY(rdev), - PUSH_ENTRY(access), - PUSH_ENTRY(modification), - PUSH_ENTRY(change), - PUSH_ENTRY(size), - PUSH_ENTRY(permissions), -}; -#undef PUSH_ENTRY - -static int -lua_attributes(lua_State *L) -{ - struct stat sb; - const char *path, *member; - size_t i; - int rc; - - path = luaL_checkstring(L, 1); - if (path == NULL) { - lua_pushnil(L); - lua_pushfstring(L, "cannot convert first argument to string"); - lua_pushinteger(L, EINVAL); - return 3; - } - - rc = stat(path, &sb); - if (rc != 0) { - lua_pushnil(L); - lua_pushfstring(L, - "cannot obtain information from file '%s': %s", path, - strerror(errno)); - lua_pushinteger(L, errno); - return 3; - } - - if (lua_isstring(L, 2)) { - member = lua_tostring(L, 2); - for (i = 0; i < nitems(members); i++) { - if (strcmp(members[i].name, member) != 0) - continue; - - members[i].push(L, &sb); - return 1; - } - return luaL_error(L, "invalid attribute name '%s'", member); - } - - /* Create or reuse existing table */ - lua_settop(L, 2); - if (!lua_istable(L, 2)) - lua_newtable(L); - - /* Export all stat data to caller */ - for (i = 0; i < nitems(members); i++) { - lua_pushstring(L, members[i].name); - members[i].push(L, &sb); - lua_rawset(L, -3); - } - return 1; -} - -#define REG_SIMPLE(n) { #n, lua_ ## n } -static const struct luaL_Reg fslib[] = { - REG_SIMPLE(attributes), - REG_SIMPLE(dir), - { NULL, NULL }, -}; -#undef REG_SIMPLE - -int -luaopen_lfs(lua_State *L) -{ - register_metatable(L); - luaL_newlib(L, fslib); - return 1; -} Index: head/stand/loader.mk =================================================================== --- head/stand/loader.mk +++ head/stand/loader.mk @@ -62,7 +62,7 @@ .include "${BOOTSRC}/lua.mk" LDR_INTERP= ${LIBLUA} LDR_INTERP32= ${LIBLUA32} -CFLAGS+= -DLUA_PATH=\"${LUAPATH}\" +CFLAGS.interp_lua.c= -DLUA_PATH=\"${LUAPATH}\" -I${FLUASRC}/modules .elif ${LOADER_INTERP} == "4th" SRCS+= interp_forth.c .include "${BOOTSRC}/ficl.mk"