Pass install scriptlet arguments to Lua as real local arguments

The code is more obvious and there's a whole lot less of it, we get
rid of a klunky global table, allow Lua scriptlets to process arguments
using native facilities for variadic functions, all in a backwards
compatible manner. What's not to like?

As a side-effect, the package count arguments now appear as integers
instead of floats, which is much saner in the context. Lua will
automatically convert numbers as necessary so this should not break
anything.
This commit is contained in:
Panu Matilainen 2020-10-08 11:05:51 +03:00
parent 192cbafcb2
commit 717a3f7ecf
3 changed files with 14 additions and 28 deletions

View File

@ -103,33 +103,17 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,
{
rpmRC rc = RPMRC_FAIL;
#ifdef WITH_LUA
ARGV_t argv = argvp ? *argvp : NULL;
rpmlua lua = NULL; /* Global state. */
rpmluav var = rpmluavNew();
int cwd = -1;
rpmlog(RPMLOG_DEBUG, "%s: running <lua> scriptlet.\n", sname);
/* Create arg variable */
rpmluaPushTable(lua, "arg");
rpmluavSetListMode(var, 1);
rpmluaSetNextFileFunc(nextFileFunc->func, nextFileFunc->param);
if (argv) {
char **p;
for (p = argv; *p; p++) {
rpmluavSetValue(var, RPMLUAV_STRING, *p);
rpmluaSetVar(lua, var);
}
}
if (arg1 >= 0) {
rpmluavSetValueNum(var, arg1);
rpmluaSetVar(lua, var);
}
if (arg2 >= 0) {
rpmluavSetValueNum(var, arg2);
rpmluaSetVar(lua, var);
}
rpmluaPop(lua);
if (arg1 >= 0)
argvAddNum(argvp, arg1);
if (arg2 >= 0)
argvAddNum(argvp, arg2);
/* Lua scripts can change our cwd and umask, save and restore */
cwd = open(".", O_RDONLY);
@ -138,7 +122,8 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,
umask(oldmask);
pid_t pid = getpid();
if (chdir("/") == 0 && rpmluaRunScript(lua, script, sname, NULL, NULL) == 0) {
if (chdir("/") == 0 &&
rpmluaRunScript(lua, script, sname, NULL, *argvp) == 0) {
rc = RPMRC_OK;
}
if (pid != getpid()) {
@ -154,10 +139,6 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,
close(cwd);
umask(oldmask);
}
rpmluaDelVar(lua, "arg");
rpmluavFree(var);
#else
rpmlog(lvl, _("<lua> scriptlet support not built in\n"));
#endif

View File

@ -589,13 +589,17 @@ int rpmluaRunScript(rpmlua _lua, const char *script, const char *name,
INITSTATE(_lua, lua);
lua_State *L = lua->L;
int ret = -1;
static const char *lualocal =
"local opt = select(1, ...); local arg = select(2, ...);";
if (name == NULL)
name = "<lua>";
if (script == NULL)
script = "";
if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
char *buf = rstrscat(NULL, lualocal, script, NULL);
if (luaL_loadbuffer(L, buf, strlen(buf), name) != 0) {
rpmlog(RPMLOG_ERR, _("invalid syntax in lua script: %s\n"),
lua_tostring(L, -1));
lua_pop(L, 1);
@ -645,6 +649,7 @@ int rpmluaRunScript(rpmlua _lua, const char *script, const char *name,
ret = 0;
exit:
free(buf);
return ret;
}

View File

@ -256,7 +256,7 @@ filetriggerin(/foo*)<lua>:
filetriggerin(/usr/bin*): 0
/usr/bin/hello
filetriggerin(/usr/bin*)<lua>: 0.0
filetriggerin(/usr/bin*)<lua>: 0
/usr/bin/hello
transfiletriggerin(/usr/bin*): 0