Re: [PATCH] readutmp: load libsystemd with dlopen instead of linking

Paul Eggert <[email protected]> Thu, 16 Jul 2026 10:49:37 -0700
Newsgroups gmane.comp.lib.gnulib.bugs
Organization UCLA Computer Science Department
Message-ID <[email protected]>
On 2026-07-16 07:40, Luca Boccassi wrote:
> It is clearly not mandatory functionality, as the package works just
> fine without it, minus some optional features that are seldomly
> needed.

If 'who' always fails, is coreutils working "just fine"? I used "who" 
before reading your email this morning (to look into a problem involving 
authentication and backups), and if 'who' had failed due to a missing 
library I would not have said coreutils is working "just fine".

That being said, to cater to a user population that thinks coreutils 
works "just fine" even if 'who' always fails, how about if we instead 
look into another idea that I think was briefly mentioned earlier: 
namely, packagers run a shell command "optional-libsystemd who pinky 
users", where optional-libsystemd is something like the attached script.

The optional-libsystemd script could be generalized to do something 
similar for other dynamic libraries that have this issue. (As an aside, 
it is annoying that objcopy makes this sort of thing such a pain but 
perhaps objcopy could be improved to make it easier.)

Although the script puts a bit of the burden on the packagers, the 
feature's burden must go *somewhere*, and since packagers want the 
feature they are more likely to maintain it well.
optional-libsystemd (text/plain, 881 B)
#!/bin/sh

tmpfile=
json='[{"type":"shared","soname":"libsystemd.so.0","priority":"suggested"}]'

for target; do
  case $target in
    -*) echo "$0: usage: $0 executable-file ..."; exit
  esac

  case $tmpfile in
    ('')
      size=${#json}
      encoded_size=$(printf '\\%o\\%o\\%o\\%o' \
			    $((size & 255)) \
			    $((size >> 8 & 255)) \
			    $((size >> 16 & 255)) \
			    $((size >> 24 & 255)))
      trap '
        status=$?
	case $tmpfile in
	  (?*) case $status in
		 (0) exec rm -f -- "$tmpfile"
	       esac
	       rm -f -- "$tmpfile"
	esac
	exit $status
      ' EXIT HUP INT PIPE TERM
      tmpfile=$(mktemp) || exit
      printf '\000\000\000\000%b\156\174\100\100%s' "$encoded_size" "$json" \
	 >"$tmpfile" || exit
  esac

  objcopy --add-section .note.dlopen="$tmpfile" \
    --set-section-flags .note.dlopen=readonly,contents \
    -- "$target" || exit
done