Commit Graph

1465 Commits

Author SHA1 Message Date
Panu Matilainen e7b80af136 Move redirect2null() out of posix extensions but preserve compatibility
posix.redirect2null() is a decidedly rpm-specific, it should've really
always been rpm.redirect2null(). Move the code to rpmlua.c and make
it available in the rpm-namespace, but to preserve script compatibility
add it to the posix module too.

One step closer to unforking the posix extensions which is more or less
a pre-requisite for ticket #165.
2019-03-01 14:56:31 +02:00
Panu Matilainen b1db055984 Raise an actual macro error if %{uncompress:...} fails 2019-02-25 16:29:06 +02:00
Panu Matilainen 6d4c68ba10 Modernize Lua library/module initialization, drop support for Lua < 5.2
Replace long since deprecated luaL_openlib() with modern counterparts
luaL_newlib() and luaL_setfuncs() and use luaL_requiref() for
loading our modules (these changes needed to go hand in hand, otherwise
it blows up every which way). Because these functions are only available
in Lua >= 5.2, this means we can drop the other compat checks as well,
just update the documenation for the new version requirement.

This also means that rpm now works on a modern Lua (tested with 5.3.5)
without requiring any compat modules and defines to be present in Lua. Whee!

Patch based on work done by @daurnimator in PR #169.

Resolves: #166
2019-02-21 16:02:52 +02:00
Panu Matilainen 1c433661ea Move lua os.exit() override from posix module to rpmlua
It was always an ugly hack and wrong to be in the posix module to
begin with, this makes the initialization and all much saner. And
is actually less code too.
2019-02-21 15:52:43 +02:00
Panu Matilainen 6974274db2 Move lua fork-tracking variable to librpmio
Having the rpm-specific fork-tracking variable accessible only inside
the posix module forces us to put stuff in there that just doesn't
belong at all, such as os.exit() override. Moving it to librpmio
allows us to move such things to rpmlua.c where they belong.

Exporting integers like this is not exactly a good library design,
but this is supposed to be just a temporary crutch to get the other
pieces in place before changing the actual mechanism.
2019-02-21 15:32:16 +02:00
Panu Matilainen 09884d87d5 Unbreak build on Lua < 5.3.4 again
This should've been moved along with the sole LUA_LOADED_TABLE user
in commit 62bd62286a, oops.
2019-02-21 12:57:10 +02:00
Panu Matilainen 770bbc5c56 Make rpmlua structures fully opaque outside rpmlua.c
Now that we finally can... opaque is good. Remove the "lua internal"
defines and move relevant includes where they belong.
No functional changes.
2019-02-21 12:30:50 +02:00
Panu Matilainen 62bd62286a Add a rpmlua wrapper function for registering libraries, use it
Eliminates the need for accessing what are supposed to be private
rpmlua fields from the outside. This does sacrifice the "perfect"
wrapping in rpmlua.h because it now needs to include lauxlib.h,
but defining our own struct just to avoid having to include a file
we'll be including in the code anyway doesn't seem worth it...
No functional changes.
2019-02-21 12:26:31 +02:00
Panu Matilainen decd85bf8a Remove redundant #ifdefs, these are not compiled at all if lua not enabled 2019-02-21 11:56:35 +02:00
Panu Matilainen 61b0287831 Don't let rpmlog() affect errno
There are any number of things that can go wrong and affect errno
inside rpmlog(), but having a function that by its declaration cannot
fail messing with errno is pretty dumb. Always save and restore
errno from rpmlog().
2019-01-17 13:11:06 +02:00
Panu Matilainen 4fa27e084e Convert %define, %global, %undefine and %dump to work via lookup table too
These are very different from the other built-ins as these do their
own parsing and return a continue address, so we need a separate
prototype for them. Having two pointers for each macro makes the table
a bit ugly but the alternative of tracking type by some other means
would lose type-safety. Other than all the boilerplate needed, this is
remarkably straightforward. No functional changes.

All built-in macros are now invoked via the lookup-table, which means
that adding new built-ins just got more straightforward and less ad hocey
pokey.
2019-01-15 17:03:47 +02:00
Panu Matilainen 93cda82b22 Convert %{trace} to work via the macro lookup table
%trace differs from the others as it doesn't take any arguments,
it just silently eats any passed. Not that it really matters here.
No functional changes.
2019-01-15 15:40:43 +02:00
Panu Matilainen 672c9e378b Convert %{load:...} to work via the macro lookup table
Annoyingly the amount of other boilerplate makes this slightly more code
than the original, but then saner code isn't always smaller, and it does
make expandMacros() smaller, which can only be a good thing.
No functional changes.
2019-01-15 15:31:19 +02:00
Panu Matilainen 311c5fdb0b Convert %{echo:...}, %{warn:...} and %{error:...} to work via lookup table
Handle log level determination inside doOutput() to make the interface
match with the others and as a bonus, make expandMacros() that little
bit smaller again. Empty argument needs to be handled differently
but shouldn't affect functionality.
2019-01-15 15:30:44 +02:00
Panu Matilainen 60327e1865 Convert %{lua:...} to work via builtin lookup table
No functional changes. chkexist and negate arguments are unused for
now, but they could perhaps be used for error condition handling later
(similar to %load)
2019-01-15 15:17:24 +02:00
Panu Matilainen ad0cf2cfa9 Start using the builtin macro table for looking up macro primitives, step 1
Replace the "necessary but clunky" string comparisons in expandMacro()
with a lookup on the builtins. For starters, only the primitives
handled in doFoo() are converted, others will require varying amount
of further changes. chkexist argument is unused by doFoo() but will be
needed later for others, add now to avoid having to change more later.

No functional changes intended, anything like that would simply be a bug.
2019-01-15 15:16:17 +02:00
Panu Matilainen 1c069fe246 Add two missing builtin macros (u2p and F) to the builtins table 2019-01-15 14:21:08 +02:00
Panu Matilainen 858e8c58f6 Make macro lookupBuiltin() work with non-terminated strings
For current uses this shouldn't make any difference, but much of the
macro engine works with string lengths so to avoid having to create
\0-terminated versions of all strings we might look at...
2019-01-15 13:36:46 +02:00
Panu Matilainen e11068a484 Use %getncpus for number of parallel XZ compression threads 2019-01-15 11:19:56 +02:00
Panu Matilainen 69e8b91dcc Add a built-in macro for fetching number of CPUs, affinity aware and all
There's an increasing number of placing wanting to know the number of
CPU's for parallel processing, and increasingly these things are running
in containers and such where the total host CPU count is not meaningful.
2019-01-15 11:16:04 +02:00
daurnimator c2c5798534 Use lua_rawlen() instead of deprecated luaL_getn() 2018-10-16 12:51:09 +03:00
daurnimator 0160f99d1b Simplify setting globals by using lua_setglobal() 2018-10-16 12:50:35 +03:00
daurnimator 76ab3651be Remove use of obsolete lua_strlen() function 2018-10-16 12:50:08 +03:00
daurnimator 50e7fd3a21 Remove long deprecated lua_open() function 2018-10-16 12:50:02 +03:00
daurnimator d05b43b9f1 In rpmluaNew, move allocations to last moment 2018-10-16 12:49:58 +03:00
Panu Matilainen dd6c65044c Resurrect long since broken Lua library path
LUA_PATH global variable is not consulted when loading libraries in
Lua >= 5.1, package.path has replaced it. Rpm's Lua library path
was always supposed to be /usr/lib/rpm/lua/ but this has been broken
for the last ten years or so, oops. Make the directory a first-class
citizen: create it on install, add a macro for it, make it actually
work and ensure it stays that way by adding a test for it.
2018-10-16 11:34:07 +03:00
Panu Matilainen a59fc0b91d Cosmetics: reindent rpmSetCloseOnExec() & friends to rpm style
Introduced in commit 5e6f05cd8d and
307e28b4cb, my bad for not spotting
on review. Just white-space changes here.
2018-10-10 11:55:03 +03:00
Panu Matilainen fa10245c91 Fix buffer overrun in glob tilde expansion
Similar to 8dda888e14 but this one
noticed by covscan: not enough space for the terminating \0.
2018-10-10 11:33:30 +03:00
Panu Matilainen 7ffc4d17ff Implement thread protection locking on the string pool
The shared string pool is in a very central role in several operations,
it's kinda embarrasing that we haven't had any thread protection
on it. Not that anybody has asked either, prior to coming up as part
of #226 (to enable threaded package creation).

Test-suite and couple of smoke-tests with the #226 pass, but only
lightly tested. Then again, it's relatively straightforward. As a general
rule, locks are taken on all exported interfaces on entry and released
on exit, internal callers never lock anything. In rpm usage at least,
performance hit seems negligible.
2018-09-28 15:32:55 +03:00
Panu Matilainen 613842841f Un-oneline rpmstrPoolNumStr() for next step 2018-09-28 14:24:33 +03:00
Panu Matilainen 8e90ea931c Use helper variables for pool streq comparison
No functional changes, but will be necessary for things to come.
2018-09-28 13:49:36 +03:00
Panu Matilainen 0a6cfc17a1 Add + use an internal helper for id -> string retrieval
Ensure non-NULL pool on the outer call, internal callers don't need that.
No functional changes, just refactoring for things to come
2018-09-28 13:47:58 +03:00
Panu Matilainen 4d67755941 Check for NULL pool on the outer callers
No functional change, just minor refactor for things to come
2018-09-28 13:02:39 +03:00
Panu Matilainen 41cf6f9c80 Clean up and improve rpmlog error handling + reporting
Centralize the log failure printing to a helper function, handle
the common conditions there. Remember the last error and only
print a new one if the error differs to avoid unnecessary flooding.
Finally, make the actual message more concise and mark it for i18n.
Oh and add a testcase as well.

This will still try to perror() in vain even if it's stderr that's
returning the errors in the first place, but maybe that's perror()'s
problem and not ours.
2018-08-07 14:17:19 +03:00
Panu Matilainen dfe88a692e Fix rpmlog error handling regressions from colorization (RhBug:1597274)
Commit 78b7a009cf caused reintroduced
some stream calls whose return value is not checked, causing the
failure to log message from getting output. In addition one of the
fputs() conditions was wrong (EPIPE instead of EOF).
2018-08-07 13:19:23 +03:00
Panu Matilainen ff4b9111ae Rip out partial support for unused MD2 and RIPEMD160 digests
Inspired by #453, adding configure-checks for unused digests algorithms
seems nonsensical, at no point in rpm history have these algorithms been
used for anything in rpm so there's not even backward compatibility to
care about. So the question becomes why do we appear to have (some)
support for those unused algorithms? So lets don't, problem solved...
2018-06-26 10:49:12 +03:00
Igor Gnatenko 18e792340e lua: add rpm.execute()
At this point, if you want to avoid using shell you have only option
which is to use posix.fork() and posix.exec() which is too verbose and
not optimal (as Florian Weimer says, posix_spawn() can be implemented
more efficiently than usual fork() / execve() sequence).

Typical use-case is shown below.

-- Before
pid = posix.fork()
if pid == 0 then
  assert(posix.exec("/foo/bar"))
elseif pid > 0 then
  posix.wait(pid)
end
-- After
assert(rpm.execute("/foo/bar"))

Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2018-05-31 10:01:45 +03:00
Kir Kolyshkin 307e28b4cb rpmSetCloseOnExec: use getrlimit()
In case /proc is not available to get the actual list of opened fds,
we fall back to iterating through the list of all possible fds.

It is possible that during the course of the program execution the limit
on number of open file descriptors might be lowered, so using the
current limit, as returned by sysconf(_SC_OPEN_MAX), might omit some
fds. Therefore, it is better to use rlim_max from the structure
filled in by gertlimit(RLIMIT_NOFILE) to make sure we're checking
all fds.

This slows down the function, but only in the case /proc is not
available, which should be rare in practice.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-05-30 15:59:42 +02:00
Kir Kolyshkin 5e6f05cd8d Optimize rpmSetCloseOnExec
In case maximum number of open files limit is set too high, both
luaext/Pexec() and lib/doScriptExec() spend way too much time
trying to set FD_CLOEXEC flag for all those file descriptors,
resulting in severe increase of time it takes to execute say
rpm or dnf.

This becomes increasingly noticeable when running with e.g. under
Docker, the reason being:

> $ docker run fedora ulimit -n
> 1048576

One obvious fix is to use procfs to get the actual list of opened fds
and iterate over it. My quick-n-dirty benchmark shows the /proc approach
is about 10x faster than iterating through a list of just 1024 fds,
so it's an improvement even for default ulimit values.

Note that the old method is still used in case /proc is not available.

While at it,

 1. fix the function by making sure we modify (rather than set)
    the existing flags. As the only known flag is FD_CLOEXEC,
    this change is currently purely aesthetical, but in case
    other flags will appear it will become a real bug fix.

 2. get rid of magic number 3; use STDERR_FILENO

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>

Fixes #444
2018-05-30 15:59:27 +02:00
Kir Kolyshkin 9c3e5de324 Factor out and unify setting CLOEXEC
Commit 7a7c31f5 ("Set FD_CLOEXEC on opened files before exec from
lua script is called") copied the code that sets CLOEXEC flag on all
possible file descriptors from lib/rpmscript.c to luaext/lposix.c,
essentially creating two copies of the same code (modulo comments
and the unused assignment).

This commit moves the functionality into its own function, without
any code modifications, using the version from luaext/lposix.c.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-05-30 15:57:58 +02:00
Bernhard Rosenkränzer 2e3867ebce Fix division by zero in prelink detection, issue 420
Avoid dividing by zero when hitting an ELF section without fixed-size
entries.
Thanks to Michael Schroeder for helping trace the problem (in #420)
2018-04-09 10:52:11 +02:00
Pavlina Moravcova Varekova 2456c12894 Fix a macro end detection if the first char of a macro line is '}' (#401)
The algorithm that detects the end of a macro counts for all macro chars their level of nested. It iteratively moves from the first char of the macro further.
Before the patch the rpm function does not implement this algorithm correctly. After finishing with the last char of a macro line, it additionally skips one char of the next line. The first char in the line was omitted.

Probably affects every rpm version from this millenium.
2018-03-27 12:29:56 +02:00
Panu Matilainen 41a9a84c5a Handle missing keyring same as key not found in rpmKeyringVerifySig() 2018-03-16 10:28:28 +02:00
Panu Matilainen 6c7b63066e Revert "Don't segfault on NULL keyring in rpmKeyringVerifySig(), doh"
Not the right thing to do here afterall...

This reverts commit e7e8d6951e.
2018-03-16 10:26:43 +02:00
Panu Matilainen e7e8d6951e Don't segfault on NULL keyring in rpmKeyringVerifySig(), doh 2018-03-15 14:23:09 +02:00
Panu Matilainen c7a8104df7 Clarify Fread() and Fwrite() semantics
These have claimed to be fread() / fwrite() "clones" but never *really*
were, and have been more or less consciously directed toward read()/write()
style semantics long ago, eg 3208913bdb
and 289ba88b30 talk about this. Changing
this long-standing behavior now would be little gain for some unnecessary
pain to callers, might just as well simply document the behavior and
be done with it.
2018-02-26 15:24:17 +02:00
Panu Matilainen f7aff1193e Track and log failures when loading macro files
It's much easier for rpm to point out the location of invalid macro
definitions than it is for humans to grep all the places a given rpm
version might look at. Log the macro file path once per file in case
of failures, and additionally return and error if all definitions fail.

Based on patch by Pavlina Moravcova Varekova.
2018-01-08 13:08:45 +02:00
Pavlina Moravcova Varekova 9343ecd94c Disable redefinition or undefinition of a built-in macro
Prior to this patch if a name of a newly created macro was the same as a built-in macro name, the macro looked correctly defined. But the newly defined macro could not be used.

It is obvious that a built-in macro can not be undefined.
2018-01-08 12:53:43 +02:00
Pavlina Moravcova Varekova 25653e5db6 Consolidate macro name verification to helper function 2018-01-08 12:53:31 +02:00
Pavlina Moravcova Varekova 0032ee8c23 Don't expand %{verbose:...} argument on false condition
Prior to this patch %{verbose:...} argument was always expanded, eg:

	rpm -v --eval '%{verbose:%{echo:is verbose}}' \
	       --eval '%{!verbose:%{echo:is not verbose}}'

	is verbose

	is not verbose

Obviously both cannot be true.
2017-10-18 11:27:54 +03:00