2 * Copyright (c) 2011 Wojciech A. Koszek <wkoszek@FreeBSD.org>
3 * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include "bootstrap.h"
44 struct interp_lua_softc
{
48 static struct interp_lua_softc lua_softc
;
51 #define LDBG(...) do { \
52 printf("%s(%d): ", __func__, __LINE__); \
53 printf(__VA_ARGS__); \
60 #define LOADER_LUA LUA_PATH "/loader.lua"
65 interp_lua_realloc(void *ud __unused
, void *ptr
, size_t osize __unused
, size_t nsize
)
72 return realloc(ptr
, nsize
);
76 * The libraries commented out below either lack the proper
77 * support from libsa, or they are unlikely to be useful
78 * in the bootloader, so have been commented out.
80 static const luaL_Reg loadedlibs
[] = {
82 {LUA_LOADLIBNAME
, luaopen_package
},
83 // {LUA_COLIBNAME, luaopen_coroutine},
84 // {LUA_TABLIBNAME, luaopen_table},
85 {LUA_STRLIBNAME
, luaopen_string
},
86 // {LUA_IOLIBNAME, luaopen_io},
87 // {LUA_OSLIBNAME, luaopen_os},
88 // {LUA_MATHLIBNAME, luaopen_math},
89 // {LUA_UTF8LIBNAME, luaopen_utf8},
90 // {LUA_DBLIBNAME, luaopen_debug},
91 {"errno", luaopen_errno
},
94 {"loader", luaopen_loader
},
95 {"pager", luaopen_pager
},
99 static bool preinit_done
= false;
105 struct interp_lua_softc
*softc
= &lua_softc
;
107 lua_init_md_t
**fnpp
;
114 setenv("script.lang", "lua", 1);
115 LDBG("creating context");
117 luap
= lua_newstate(interp_lua_realloc
, NULL
);
119 printf("problem initializing the Lua interpreter\n");
124 /* "require" functions from 'loadedlibs' and set results to global table */
125 for (lib
= loadedlibs
; lib
->func
; lib
++) {
126 luaL_requiref(luap
, lib
->name
, lib
->func
, 1);
127 lua_pop(luap
, 1); /* remove lib */
130 LUA_FOREACH_SET(fnpp
)
142 struct interp_lua_softc
*softc
= &lua_softc
;
143 const char *filename
;
148 filename
= getenv("loader_lua");
149 if (filename
== NULL
)
150 filename
= LOADER_LUA
;
151 if (interp_include(filename
) != 0) {
152 const char *errstr
= lua_tostring(luap
, -1);
153 errstr
= errstr
== NULL
? "unknown" : errstr
;
154 printf("ERROR: %s.\n", errstr
);
156 setenv("autoboot_delay", "NO", 1);
163 interp_run(const char *line
)
168 struct interp_lua_softc
*softc
= &lua_softc
;
173 LDBG("executing line...");
174 if ((status
= luaL_dostring(luap
, line
)) != 0) {
177 * The line wasn't executable as lua; run it through parse to
178 * to get consistent parsing of command line arguments, then
179 * run it through cli_execute. If that fails, then we'll try it
182 command_errmsg
= NULL
;
183 if (parse(&argc
, &argv
, line
) == 0) {
184 lua_getglobal(luap
, "cli_execute");
185 for (nargc
= 0; nargc
< argc
; ++nargc
) {
186 lua_pushstring(luap
, argv
[nargc
]);
188 status
= lua_pcall(luap
, argc
, 1, 0);
189 ret
= lua_tointeger(luap
, 1);
191 if (status
!= 0 || ret
!= 0) {
193 * Lua cli_execute will pass the function back
194 * through loader.command, which is a proxy to
195 * interp_builtin_cmd. If we failed to interpret
196 * the command, though, then there's a chance
197 * that didn't happen. Call interp_builtin_cmd
198 * directly if our lua_pcall was not successful.
200 status
= interp_builtin_cmd(argc
, argv
);
203 if (command_errmsg
!= NULL
)
204 printf("%s\n", command_errmsg
);
206 printf("Command failed\n");
211 printf("Failed to parse \'%s\'\n", line
);
217 return (status
== 0 ? CMD_OK
: CMD_ERROR
);
221 interp_include(const char *filename
)
223 struct interp_lua_softc
*softc
= &lua_softc
;
225 LDBG("loading file %s", filename
);
227 return (luaL_dofile(softc
->luap
, filename
));