interp_lua.c revision 344413
1193240Ssam/*- 2193240Ssam * Copyright (c) 2011 Wojciech A. Koszek <wkoszek@FreeBSD.org> 3193240Ssam * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org> 4193240Ssam * All rights reserved. 5193240Ssam * 6193240Ssam * Redistribution and use in source and binary forms, with or without 7193240Ssam * modification, are permitted provided that the following conditions 8193240Ssam * are met: 9193240Ssam * 1. Redistributions of source code must retain the above copyright 10193240Ssam * notice, this list of conditions and the following disclaimer. 11193240Ssam * 2. Redistributions in binary form must reproduce the above copyright 12193240Ssam * notice, this list of conditions and the following disclaimer in the 13193240Ssam * documentation and/or other materials provided with the distribution. 14193240Ssam * 15193240Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16193240Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17193240Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18193240Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19193240Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20193240Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21193240Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22193240Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23193240Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24193240Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25193240Ssam * SUCH DAMAGE. 26193240Ssam */ 27193240Ssam 28193240Ssam#include <sys/cdefs.h> 29193240Ssam__FBSDID("$FreeBSD: stable/11/stand/common/interp_lua.c 344413 2019-02-21 03:18:12Z kevans $"); 30193240Ssam 31193240Ssam#include <stand.h> 32193240Ssam#include "bootstrap.h" 33193240Ssam 34193240Ssam#define lua_c 35193240Ssam 36193240Ssam#include "lstd.h" 37193240Ssam 38193240Ssam#include <lua.h> 39193240Ssam#include <ldebug.h> 40234367Sadrian#include <lauxlib.h> 41193240Ssam#include <lualib.h> 42193240Ssam 43193240Ssam#include <lerrno.h> 44193240Ssam#include <lfs.h> 45193240Ssam#include <lutils.h> 46193240Ssam 47193240Ssamstruct interp_lua_softc { 48193240Ssam lua_State *luap; 49193240Ssam}; 50193240Ssam 51193240Ssamstatic struct interp_lua_softc lua_softc; 52193240Ssam 53193240Ssam#ifdef LUA_DEBUG 54193240Ssam#define LDBG(...) do { \ 55193240Ssam printf("%s(%d): ", __func__, __LINE__); \ 56193240Ssam printf(__VA_ARGS__); \ 57193240Ssam printf("\n"); \ 58193240Ssam} while (0) 59193240Ssam#else 60193240Ssam#define LDBG(...) 61193240Ssam#endif 62257176Sglebius 63193240SsamINTERP_DEFINE("lua"); 64193240Ssam 65193240Ssamstatic void * 66193240Ssaminterp_lua_realloc(void *ud __unused, void *ptr, size_t osize __unused, size_t nsize) 67193240Ssam{ 68193240Ssam 69193240Ssam if (nsize == 0) { 70193240Ssam free(ptr); 71193240Ssam return NULL; 72193240Ssam } 73193240Ssam return realloc(ptr, nsize); 74193240Ssam} 75193240Ssam 76193240Ssam/* 77193240Ssam * The libraries commented out below either lack the proper 78193240Ssam * support from libsa, or they are unlikely to be useful 79193240Ssam * in the bootloader, so have been commented out. 80193240Ssam */ 81193240Ssamstatic const luaL_Reg loadedlibs[] = { 82193240Ssam {"_G", luaopen_base}, 83193240Ssam {LUA_LOADLIBNAME, luaopen_package}, 84193240Ssam// {LUA_COLIBNAME, luaopen_coroutine}, 85193240Ssam// {LUA_TABLIBNAME, luaopen_table}, 86193240Ssam {LUA_STRLIBNAME, luaopen_string}, 87193240Ssam// {LUA_IOLIBNAME, luaopen_io}, 88228621Sbschmidt// {LUA_OSLIBNAME, luaopen_os}, 89228621Sbschmidt// {LUA_MATHLIBNAME, luaopen_math}, 90228621Sbschmidt// {LUA_UTF8LIBNAME, luaopen_utf8}, 91193240Ssam// {LUA_DBLIBNAME, luaopen_debug}, 92193240Ssam {"errno", luaopen_errno}, 93193240Ssam {"io", luaopen_io}, 94193240Ssam {"lfs", luaopen_lfs}, 95193240Ssam {"loader", luaopen_loader}, 96193240Ssam {NULL, NULL} 97193240Ssam}; 98193240Ssam 99193240Ssamvoid 100193240Ssaminterp_init(void) 101193240Ssam{ 102193240Ssam lua_State *luap; 103199559Sjhb struct interp_lua_softc *softc = &lua_softc; 104193240Ssam const char *filename; 105193240Ssam const luaL_Reg *lib; 106193240Ssam 107193240Ssam setenv("script.lang", "lua", 1); 108193240Ssam LDBG("creating context"); 109193240Ssam 110193240Ssam luap = lua_newstate(interp_lua_realloc, NULL); 111193240Ssam if (luap == NULL) { 112193240Ssam printf("problem initializing the Lua interpreter\n"); 113193240Ssam abort(); 114193240Ssam } 115193240Ssam softc->luap = luap; 116193240Ssam 117193240Ssam /* "require" functions from 'loadedlibs' and set results to global table */ 118193240Ssam for (lib = loadedlibs; lib->func; lib++) { 119193240Ssam luaL_requiref(luap, lib->name, lib->func, 1); 120193240Ssam lua_pop(luap, 1); /* remove lib */ 121193240Ssam } 122193240Ssam 123193240Ssam filename = "/boot/lua/loader.lua"; 124193240Ssam if (interp_include(filename) != 0) { 125193240Ssam const char *errstr = lua_tostring(luap, -1); 126193240Ssam errstr = errstr == NULL ? "unknown" : errstr; 127193240Ssam printf("Startup error in %s:\nLUA ERROR: %s.\n", filename, errstr); 128193240Ssam lua_pop(luap, 1); 129193240Ssam } 130193240Ssam} 131193240Ssam 132193240Ssamint 133193240Ssaminterp_run(const char *line) 134193240Ssam{ 135193240Ssam int argc, nargc; 136193240Ssam char **argv; 137193240Ssam lua_State *luap; 138193240Ssam struct interp_lua_softc *softc = &lua_softc; 139193240Ssam int status, ret; 140193240Ssam 141193240Ssam luap = softc->luap; 142193240Ssam LDBG("executing line..."); 143193240Ssam if ((status = luaL_dostring(luap, line)) != 0) { 144193240Ssam lua_pop(luap, 1); 145193240Ssam /* 146193240Ssam * The line wasn't executable as lua; run it through parse to 147193240Ssam * to get consistent parsing of command line arguments, then 148193240Ssam * run it through cli_execute. If that fails, then we'll try it 149195377Ssam * as a builtin. 150195377Ssam */ 151193240Ssam command_errmsg = NULL; 152193240Ssam if (parse(&argc, &argv, line) == 0) { 153193240Ssam lua_getglobal(luap, "cli_execute"); 154193240Ssam for (nargc = 0; nargc < argc; ++nargc) { 155193240Ssam lua_pushstring(luap, argv[nargc]); 156193240Ssam } 157193240Ssam status = lua_pcall(luap, argc, 1, 0); 158193240Ssam ret = lua_tointeger(luap, 1); 159193240Ssam lua_pop(luap, 1); 160193240Ssam if (status != 0 || ret != 0) { 161193240Ssam /* 162193240Ssam * Lua cli_execute will pass the function back 163193240Ssam * through loader.command, which is a proxy to 164193240Ssam * interp_builtin_cmd. If we failed to interpret 165193240Ssam * the command, though, then there's a chance 166193240Ssam * that didn't happen. Call interp_builtin_cmd 167193240Ssam * directly if our lua_pcall was not successful. 168193240Ssam */ 169193240Ssam status = interp_builtin_cmd(argc, argv); 170193240Ssam } 171193240Ssam if (status != 0) { 172193240Ssam if (command_errmsg != NULL) 173193240Ssam printf("%s\n", command_errmsg); 174193240Ssam else 175193240Ssam printf("Command failed\n"); 176193240Ssam status = CMD_ERROR; 177193240Ssam } 178193240Ssam free(argv); 179193240Ssam } else { 180193240Ssam printf("Failed to parse \'%s\'\n", line); 181193240Ssam status = CMD_ERROR; 182193240Ssam } 183193240Ssam } 184193240Ssam 185193240Ssam return (status == 0 ? CMD_OK : CMD_ERROR); 186193240Ssam} 187193240Ssam 188193240Ssamint 189193240Ssaminterp_include(const char *filename) 190193240Ssam{ 191267992Shselasky struct interp_lua_softc *softc = &lua_softc; 192193240Ssam 193193240Ssam LDBG("loading file %s", filename); 194267992Shselasky 195193240Ssam return (luaL_dofile(softc->luap, filename)); 196193240Ssam} 197267992Shselasky