Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter Lua deprecation warnings based on the originating rpm version #3270

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 41 additions & 30 deletions lib/rpmscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct rpmScript_s {
char *body; /* script body */
char *descr; /* description for logging */
rpmscriptFlags flags; /* flags to control operation */
char *rpmver; /* builder rpm version */
int chroot; /* chrooted script? */
struct scriptNextFileFunc_s *nextFileFunc; /* input function */
};
Expand Down Expand Up @@ -132,21 +133,20 @@ int rpmScriptChrootOut(rpmScript script)
* Run internal Lua script.
*/
static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,
const char *sname, rpmlogLvl lvl, FD_t scriptFd,
ARGV_t * argvp, const char *script, int arg1, int arg2,
scriptNextFileFunc nextFileFunc)
rpmScript script, rpmlogLvl lvl, FD_t scriptFd,
ARGV_t * argvp, int arg1, int arg2)
{
char *scriptbuf = NULL;
char *scriptbuf = script->body;
rpmRC rc = RPMRC_FAIL;
rpmlua lua = rpmluaGetGlobalState();
lua_State *L = (lua_State *)rpmluaGetLua(lua);
int cwd = -1;

rpmlog(RPMLOG_DEBUG, "%s: running <lua> scriptlet.\n", sname);
rpmlog(RPMLOG_DEBUG, "%s: running <lua> scriptlet.\n", script->descr);

if (nextFileFunc) {
if (script->nextFileFunc) {
lua_getglobal(L, "rpm");
lua_pushlightuserdata(L, nextFileFunc);
lua_pushlightuserdata(L, script->nextFileFunc);
lua_pushcclosure(L, &next_file, 1);
lua_setfield(L, -2, "next_file");
}
Expand All @@ -168,11 +168,10 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,

if (arg1 >= 0 || arg2 >= 0) {
/* Hack to convert arguments to numbers for backwards compat. Ugh. */
rstrscat(&scriptbuf,
scriptbuf = rstrscat(NULL,
arg1 >= 0 ? "arg[2] = tonumber(arg[2]);" : "",
arg2 >= 0 ? "arg[3] = tonumber(arg[3]);" : "",
script, NULL);
script = scriptbuf;
script->body, NULL);
}

/* Lua scripts can change our cwd and umask, save and restore */
Expand All @@ -181,10 +180,19 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,
mode_t oldmask = umask(0);
umask(oldmask);

lua_pushstring(L, "RPM_PACKAGE_RPMVERSION");
lua_pushstring(L, script->rpmver);
lua_settable(L, LUA_REGISTRYINDEX);

if (chdir("/") == 0 &&
rpmluaRunScript(lua, script, sname, NULL, *argvp) == 0) {
rpmluaRunScript(lua, scriptbuf, script->descr, NULL, *argvp) == 0) {
rc = RPMRC_OK;
}

lua_getfield(L, LUA_REGISTRYINDEX, "RPM_PACKAGE_RPMVERSION");
lua_pushnil(L);
lua_settable(L, LUA_REGISTRYINDEX);

/* This failing would be fatal, return something different for it... */
if (fchdir(cwd)) {
rpmlog(RPMLOG_ERR, _("Unable to restore current directory: %m"));
Expand All @@ -193,14 +201,15 @@ static rpmRC runLuaScript(rpmPlugins plugins, ARGV_const_t prefixes,
close(cwd);
umask(oldmask);
}
free(scriptbuf);
if (scriptbuf != script->body)
free(scriptbuf);

if (prefixes) {
lua_pushnil(L);
lua_setglobal(L, "RPM_INSTALL_PREFIX");
}

if (nextFileFunc) {
if (script->nextFileFunc) {
lua_pushnil(L);
lua_setfield(L, -2, "next_file");
lua_pop(L, 1); /* "rpm" global */
Expand Down Expand Up @@ -308,9 +317,8 @@ static char * writeScript(const char *cmd, const char *script)
* Run an external script.
*/
static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
const char *sname, rpmlogLvl lvl, FD_t scriptFd,
ARGV_t * argvp, const char *script, int arg1, int arg2,
scriptNextFileFunc nextFileFunc)
rpmScript script, rpmlogLvl lvl, FD_t scriptFd,
ARGV_t * argvp, int arg1, int arg2)
{
FD_t out = NULL;
char * fn = NULL;
Expand All @@ -322,14 +330,14 @@ static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
char *mline = NULL;
rpmRC rc = RPMRC_FAIL;

rpmlog(RPMLOG_DEBUG, "%s: scriptlet start\n", sname);
rpmlog(RPMLOG_DEBUG, "%s: scriptlet start\n", script->descr);

if (script) {
fn = writeScript(*argvp[0], script);
if (script->body) {
fn = writeScript(*argvp[0], script->body);
if (fn == NULL) {
rpmlog(RPMLOG_ERR,
_("Couldn't create temporary file for %s: %s\n"),
sname, strerror(errno));
script->descr, strerror(errno));
goto exit;
}

Expand Down Expand Up @@ -364,18 +372,18 @@ static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
}
if (out == NULL) {
rpmlog(RPMLOG_ERR, _("Couldn't duplicate file descriptor: %s: %s\n"),
sname, strerror(errno));
script->descr, strerror(errno));
goto exit;
}

pid = fork();
if (pid == (pid_t) -1) {
rpmlog(RPMLOG_ERR, _("Couldn't fork %s: %s\n"),
sname, strerror(errno));
script->descr, strerror(errno));
goto exit;
} else if (pid == 0) {/* Child */
rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n",
sname, *argvp[0], (unsigned)getpid());
script->descr, *argvp[0], (unsigned)getpid());

fclose(in);
dup2(inpipe[0], STDIN_FILENO);
Expand All @@ -390,7 +398,8 @@ static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
close(inpipe[0]);
inpipe[0] = 0;

if (nextFileFunc) {
if (script->nextFileFunc) {
scriptNextFileFunc nextFileFunc = script->nextFileFunc;
while ((line = nextFileFunc->func(nextFileFunc->param)) != NULL) {
size_t size = strlen(line);
size_t ret_size;
Expand Down Expand Up @@ -418,18 +427,18 @@ static rpmRC runExtScript(rpmPlugins plugins, ARGV_const_t prefixes,
} while (reaped == -1 && errno == EINTR);

rpmlog(RPMLOG_DEBUG, "%s: waitpid(%d) rc %d status %x\n",
sname, (unsigned)pid, (unsigned)reaped, status);
script->descr, (unsigned)pid, (unsigned)reaped, status);

if (reaped < 0) {
rpmlog(lvl, _("%s scriptlet failed, waitpid(%d) rc %d: %s\n"),
sname, pid, reaped, strerror(errno));
script->descr, pid, reaped, strerror(errno));
} else if (!WIFEXITED(status) || WEXITSTATUS(status)) {
if (WIFSIGNALED(status)) {
rpmlog(lvl, _("%s scriptlet failed, signal %d\n"),
sname, WTERMSIG(status));
script->descr, WTERMSIG(status));
} else {
rpmlog(lvl, _("%s scriptlet failed, exit status %d\n"),
sname, WEXITSTATUS(status));
script->descr, WEXITSTATUS(status));
}
} else {
/* if we get this far we're clear */
Expand Down Expand Up @@ -482,9 +491,9 @@ rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd,

if (rc != RPMRC_FAIL) {
if (script_type & RPMSCRIPTLET_EXEC) {
rc = runExtScript(plugins, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2, script->nextFileFunc);
rc = runExtScript(plugins, prefixes, script, lvl, scriptFd, &args, arg1, arg2);
} else {
rc = runLuaScript(plugins, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2, script->nextFileFunc);
rc = runLuaScript(plugins, prefixes, script, lvl, scriptFd, &args, arg1, arg2);
}
}

Expand Down Expand Up @@ -530,6 +539,7 @@ static rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body,
script->type = getScriptType(tag);
script->flags = getDefFlags(tag) | flags;
script->body = (body != NULL) ? xstrdup(body) : NULL;
script->rpmver = headerGetAsString(h, RPMTAG_RPMVERSION);
script->chroot = 1;
rasprintf(&script->descr, "%%%s%s(%s)", prefix, tag2sln(tag), nevra);

Expand Down Expand Up @@ -706,6 +716,7 @@ rpmScript rpmScriptFree(rpmScript script)
free(script->args);
free(script->body);
free(script->descr);
free(script->rpmver);
delete script->nextFileFunc;
delete script;
}
Expand Down
6 changes: 3 additions & 3 deletions rpmio/lposix.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ static int Pmkfifo(lua_State *L) /** mkfifo(path) */

static int Pexec(lua_State *L) /** exec(path,[args]) */
{
check_deprecated(L, "posix.exec");
check_deprecated(L, "posix.exec", "4.20.0");

const char *path = luaL_checkstring(L, 1);
int i,n=lua_gettop(L);
Expand All @@ -354,7 +354,7 @@ static int Pexec(lua_State *L) /** exec(path,[args]) */

static int Pfork(lua_State *L) /** fork() */
{
check_deprecated(L, "posix.fork");
check_deprecated(L, "posix.fork", "4.20.0");

pid_t pid = fork();
if (pid == 0) {
Expand All @@ -366,7 +366,7 @@ static int Pfork(lua_State *L) /** fork() */

static int Pwait(lua_State *L) /** wait([pid]) */
{
check_deprecated(L, "posix.wait");
check_deprecated(L, "posix.wait", "4.20.0");

pid_t pid = luaL_optinteger(L, 1, -1);
return pushresult(L, waitpid(pid, NULL, 0), NULL);
Expand Down
2 changes: 1 addition & 1 deletion rpmio/lposix.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <rpm/rpmutil.h>

RPM_GNUC_INTERNAL
void check_deprecated(lua_State *L, const char *func);
void check_deprecated(lua_State *L, const char *func, const char *deprecated_in);

RPM_GNUC_INTERNAL
int luaopen_posix (lua_State *L);
Expand Down
22 changes: 18 additions & 4 deletions rpmio/rpmlua.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ static int rpm_redirect2null(lua_State *L)
{
int target_fd, fd, r, e;

check_deprecated(L, "rpm.redirect2null");
check_deprecated(L, "rpm.redirect2null", "4.20.0");

if (!_rpmlua_have_forked)
return luaL_error(L, "redirect2null not permitted in this context");
Expand Down Expand Up @@ -1365,8 +1365,22 @@ static int luaopen_rpm(lua_State *L)
return 1;
}

void check_deprecated(lua_State *L, const char *func)
void check_deprecated(lua_State *L, const char *func, const char *deprecated_in)
{
fprintf(stderr,
"warning: %s(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead\n", func);
int warn = 1;
lua_getfield(L, LUA_REGISTRYINDEX, "RPM_PACKAGE_RPMVERSION");
if (lua_isstring(L, -1)) {
rpmver v1 = rpmverParse(lua_tostring(L, -1));
rpmver v2 = rpmverParse(deprecated_in);
if (v1 && v2 && rpmverCmp(v1, v2) < 0)
warn = 0;
rpmverFree(v2);
rpmverFree(v1);
}
lua_pop(L, 1);

if (warn) {
fprintf(stderr,
"warning: %s(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead\n", func);
}
}
Binary file added tests/data/RPMS/luafork-1.0-1.noarch.rpm
Binary file not shown.
22 changes: 22 additions & 0 deletions tests/data/SPECS/luafork.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Name: luafork
Version: 1.0
Release: 1
License: Public domain
Summary: Testing Lua fork behavior
BuildArch: noarch

%description
%{summary}

%pre -p <lua>
local pid = posix.fork()
if pid == 0 then
io.stdout:write("child\n")
os.exit(0)
elseif pid > 0 then
posix.wait(pid)
else
io.stderr:write("fork failed")
end

%files
28 changes: 28 additions & 0 deletions tests/rpmscript.at
Original file line number Diff line number Diff line change
Expand Up @@ -801,3 +801,31 @@ runroot_other test -f /tmp/scriptwrite.log
[])
RPMTEST_CLEANUP

AT_SETUP([deprecated Lua functions])
AT_KEYWORDS([script lua])

# binary pre-built on rpm 4.18 should emit no warnings
RPMTEST_CHECK([
RPMDB_INIT
runroot rpm -U /data/RPMS/luafork-1.0-1.noarch.rpm
],
[0],
[child
],
[])

RPMTEST_CHECK([
RPMDB_INIT

runroot rpmbuild -bb --quiet /data/SPECS/luafork.spec
runroot rpm -U /build/RPMS/noarch/luafork-1.0-1.noarch.rpm
],
[0],
[child
],
[warning: posix.fork(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead
warning: posix.wait(): .fork(), .exec(), .wait() and .redirect2null() are deprecated, use rpm.spawn() or rpm.execute() instead
])

RPMTEST_CLEANUP

Loading