Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package blog for openSUSE:Factory checked in 
at 2026-07-10 17:34:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/blog (Old)
 and      /work/SRC/openSUSE:Factory/.blog.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "blog"

Fri Jul 10 17:34:30 2026 rev:28 rq:1364730 version:2.46

Changes:
--------
--- /work/SRC/openSUSE:Factory/blog/blog.changes        2026-07-06 
12:28:01.926437575 +0200
+++ /work/SRC/openSUSE:Factory/.blog.new.1991/blog.changes      2026-07-10 
17:35:11.792585430 +0200
@@ -1,0 +2,110 @@
+Thu Jul  9 13:40:53 UTC 2026 - Dr. Werner Fink <[email protected]>
+
+- Update to version 2.46
+  Implement Plymouth-compatible display-message and hide-message commands
+
+  This commit adds support for the display-message and hide-message
+  Plymouth commands, allowing external tools to print status updates
+  directly to the boot console via blogctl.
+
+  Key changes:
+    Add MAGIC_SHOW_MSG and MAGIC_HIDE_MSG protocols to blogctl and
+    parse the --text= argument using getopt_long_only().
+    Broadcast display-message payloads to all active hardware consoles
+    via c->out() to ensure immediate visual feedback, while simultaneously
+    logging it to /var/log/boot.log via copylog().
+    Add \r\n line endings to printed messages to prevent the staircase
+    effect on serial terminals operating in raw mode.
+    Handle hide-message as a visual no-op (replying with an ACK only)
+    to deliberately avoid ANSI clear-screen sequences that would corrupt
+    the output on line-based, half-duplex consoles like the s390x 3215.
+    Update the blogctl.8 manual page to document the new commands and
+    their specific behavior regarding screen clearing.
+
+  Implement Plymouth-compatible ask-for-password and ask-question commands
+
+  This commit extends blogctl to act as a lightweight, fully functional
+  replacement for Plymouth's interactive prompt commands, allowing scripts
+  to securely ask for passwords or questions on the system console.
+
+  Key changes:
+    Add support for ask-for-password and ask-question in blogctl.
+    Use getopt_long_only() to robustly parse GNU-style long options
+    (--prompt, --command, --number-of-tries, --dont-pause-progress).
+    Offload the retry-loop and command execution (popen) entirely to
+    the blogctl client, keeping the blogd daemon simple and secure.
+    Fix an epoll EEXIST crash in console.c by separating the daemon's
+    process state (asking) from the requested prompt type (ask_mode),
+    resolving a race condition during socket handler registration.
+    Comply strictly with the Plymouth protocol: enforce 1-byte prompt
+    length limits, handle little-endian length headers (le32toh),
+    and ensure null-terminated payloads via asprintf.
+    Update the blogctl.8 manual page to document the new commands.
+
+  Back to use constructor for initial seed
+  for the process lifetime and inherited across fork()
+
+  Make tty wait logic real and fix SIGHUP/inotify cleanup
+  Better in-memory reversible obfuscation for cached passwords
+  This is not cryptographic protection against a memory-reading attacker.
+  It is only meant to avoid trivial/plaintext exposure in memory.
+
+  Fix resource leaks and harden IPC validations
+  This commit addresses several issues found by static code analysis,
+  focusing on memory hygiene, file descriptor management, and robust
+  error handling.
+
+  Key changes:
+    Fix memory and file descriptor leaks in error paths (proc.c, shm.c, tty.c)
+    and ensure all pending coldstart requests are freed on shutdown.
+    Harden the systemd ask-password interface by adding boundary checks
+    for UNIX socket paths, verifying sendto payloads, and gracefully
+    handling missing directories during early boot without fatal errors.
+    Improve IPC protocol safety by strictly validating the MAGIC_CHROOT
+    argument (must be an absolute path) and sending an explicit NACK on 
failure.
+    Prevent stale terminal states on s390x by clearing the VMCP cache
+    prior to parsing a new QUERY TERMINAL reply.
+
+  User the --wait option of the blogctl quit command
+  Add an --wait option specially for quit of blogctl
+
+  Fix gh##7
+  setting blog.silent=true causes it to be non-silent
+
+  Make shared library a executable
+
+  Refactor daemon to use synchronous signalfd and epoll event loop
+  This commit migrates the core architecture from traditional, asynchronous
+  signal handling to a modern, synchronous event loop using signalfd. By
+  integrating signal handling directly into the epoll multiplexer, we eliminate
+  race conditions, unexpected EINTR interruptions during I/O operations, and
+  complex reentrancy issues.
+  
+  Key changes:
+    Add setup_signalfd() to block essential signals (SIGINT, SIGQUIT, SIGTERM,
+    SIGSYS, SIGIO, SIGCHLD) globally and route them through a dedicated file
+    descriptor monitored by epoll.
+    Shield epoll_pwait() using a fully populated signal mask (omask) to
+    guarantee uninterrupted I/O processing.
+    Prevent socket handlers (MAGIC_SYS_INIT, MAGIC_CLOSE) from accidentally
+    unblocking signals and resetting dispositions when signalfd is active.
+    Sanitize the inherited signal mask in forked child processes
+    (e.g., systemd password prompts on tty) by resetting it to an empty
+    mask via sigprocmask(), ensuring agents run without restrictions.
+    Replace the ALIGNED_SIZEOF macro with a cleaner align_up(type, boundary)
+    macro and fix memset() sizes to correctly zero out trailing padding bytes.
+    Update the Makefile to compile a stripped-down fallback object
+    (signals_stripped.o compiled with -DNO_SIGNALFD) to ensure the passive
+    libblogger.so library remains unaffected by the signalfd architecture.
+
+  Some minor changes in quit and umount unit services
+
+  The HVC consoles are like sclp console
+  and can do colours as well
+
+-------------------------------------------------------------------
+Mon Jul  6 09:10:22 UTC 2026 - Dr. Werner Fink <[email protected]>
+
+- Silent some rpmlint warnings 
+
+-------------------------------------------------------------------

Old:
----
  showconsole-2.45.tar.gz

New:
----
  showconsole-2.46.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ blog.spec ++++++
--- /var/tmp/diff_new_pack.jpigmN/_old  2026-07-10 17:35:14.772687399 +0200
+++ /var/tmp/diff_new_pack.jpigmN/_new  2026-07-10 17:35:14.776687536 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           blog
-Version:        2.45
+Version:        2.46
 %define sonum   2
 Release:        0
 Summary:        Boot logging
@@ -66,6 +66,7 @@
 Requires:       udev
 Conflicts:      plymouth
 Conflicts:      plymouth-dracut
+BuildArch:      noarch
 
 %description   plymouth
 The Blogd daemon can be used as a replacement for Plymouth in situations where
@@ -143,7 +144,6 @@
 %endif
 
 %files
-%defattr(-,root,root)
 %license COPYING
 %doc README
 %if 0%{?suse_version} < 1550
@@ -169,15 +169,13 @@
 %doc %{_mandir}/man8/showconsole.8.gz
 
 %files -n libblogger%{sonum}
-%{_libdir}/libblogger.so.*
+%attr(0755,root,root) %{_libdir}/libblogger.so.*
 
 %files devel
-%defattr(-,root,root)
 %{_includedir}/libblogger.h
 %{_libdir}/libblogger.so
 
 %files plymouth
-%defattr(-,root,root)
 %dir %{_prefix}/lib/dracut/
 %dir %{_prefix}/lib/dracut/modules.d/
 %dir %{_prefix}/lib/dracut/modules.d/99blog/

++++++ blog-rpmlintrc ++++++
--- /var/tmp/diff_new_pack.jpigmN/_old  2026-07-10 17:35:14.808688631 +0200
+++ /var/tmp/diff_new_pack.jpigmN/_new  2026-07-10 17:35:14.816688905 +0200
@@ -1,3 +1,4 @@
 addFilter(".*systemd-service-without-service_del_p.*")
 addFilter(".*systemd-service-without-service_add_p.*")
+addFilter(".*W:.*no-%check-section.*")
 

++++++ showconsole-2.45.tar.gz -> showconsole-2.46.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/Makefile 
new/showconsole-2.46/Makefile
--- old/showconsole-2.45/Makefile       2026-07-02 11:25:23.000000000 +0200
+++ new/showconsole-2.46/Makefile       2026-07-09 15:29:51.000000000 +0200
@@ -15,7 +15,7 @@
 DEBUG   =
 DESTDIR         =
 MAJOR   :=     2
-MINOR   :=     45
+MINOR   :=     46
 VERSION         :=     $(MAJOR).$(MINOR)
 DATE    =      $(shell date +'%d%b%y' | tr '[:lower:]' '[:upper:]')
 COPTS    =
@@ -48,6 +48,8 @@
        INSTCON = install $(INSTDOCFLAGS)
    INSTSCRFLAGS = -c -m 0755
        INSTSCR = install $(INSTSCRFLAGS)
+    INSTSOFLAGS = -c -m 0755
+        INSTSO = install $(INSTSOFLAGS)
           LINK = ln -sf
             AR ?= ar
             LD ?= ld -shared -O2
@@ -86,11 +88,14 @@
 libconsole.a: $(patsubst %.c,%.o,$(libfiles)) $(L)libconsole.h listing.h
        $(AR) rusv $@ $^
 
+$(L)signals_stripped.o: $(L)signals.c
+       $(CC) $(CFLAGS) $(CLOOP) -DNO_SIGNALFD -D_REENTRANT -fPIC -o $@ -c $< 
-pthread
+
 libblogger.o:  libconsole.a
 libblogger.o:  libblogger.c libblogger.h
        $(CC) $(CFLAGS) $(CLOOP) -fPIC -c $<
 
-libblogger.so: libblogger.o libconsole/signals.o
+libblogger.so: libblogger.o libconsole/signals_stripped.o
        $(CC) -shared  -Wl,-O2 -Wl,-soname=$@.$(MAJOR) -o $@ $^
 
 showconsole:   showconsole.c libconsole.a
@@ -131,7 +136,7 @@
        $(INSTBIN) blogctl              $(DESTDIR)$(SBINDIR)/
        $(INSTDOC) blogctl.8            $(DESTDIR)$(SDOCDIR)/
        $(INSTCON) libblogger.h         $(DESTDIR)$(INCDIR)/
-       $(INSTCON) libblogger.so        
$(DESTDIR)$(LIBDIR)/libblogger.so.$(MAJOR).$(MINOR)
+       $(INSTSO)  libblogger.so        
$(DESTDIR)$(LIBDIR)/libblogger.so.$(MAJOR).$(MINOR)
        $(INSTBIN) isserial             $(DESTDIR)$(SBINDIR)/
        $(INSTDOC) isserial.8           $(DESTDIR)$(SDOCDIR)/
        $(INSTSCR) module-setup.sh      $(DESTDIR)$(DRACUTMOD)/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/blog-quit.service 
new/showconsole-2.46/blog-quit.service
--- old/showconsole-2.45/blog-quit.service      2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/blog-quit.service      2026-07-09 15:29:51.000000000 
+0200
@@ -2,10 +2,10 @@
 Description=Tell blogd to Quit
 DefaultDependencies=no
 Conflicts=shutdown.target
-After=rc-local.service blog.service systemd-user-sessions.service
+After=default.target rc-local.service blog.service 
systemd-user-sessions.service
 
 [Service]
 Type=oneshot
 TimeoutSec=20
 RemainAfterExit=yes
-ExecStart=-/sbin/blogctl quit
+ExecStart=-/sbin/blogctl quit --wait
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/blog-umount.service.in 
new/showconsole-2.46/blog-umount.service.in
--- old/showconsole-2.45/blog-umount.service.in 2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/blog-umount.service.in 2026-07-09 15:29:51.000000000 
+0200
@@ -10,4 +10,5 @@
 Type=oneshot
 TimeoutSec=0
 RemainAfterExit=yes
+ExecStart=/bin/true
 ExecStop=/sbin/blogctl close
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/blogctl.8 
new/showconsole-2.46/blogctl.8
--- old/showconsole-2.45/blogctl.8      2026-07-02 11:25:23.000000000 +0200
+++ new/showconsole-2.46/blogctl.8      2026-07-09 15:29:51.000000000 +0200
@@ -13,7 +13,7 @@
 .SH SYNOPSIS
 .\"
 .B /sbin/blogctl
-.RI [ ping | quit | root=<path> | ready | close ]
+.RI [ ping | quit\ [--wait] | root=<path> | ready | close | ask-for-password | 
ask-question | display-message | hide-message ]
 .SH DESCRIPTION
 .B blogctl
 may be used to check if a
@@ -22,15 +22,67 @@
 .SH COMANDS
 The following commands are known:
 .TP
+.B ask-for-password
+Ask the user for a password on the system console.
+.RS
+.TP
+.BI \-\-command= STRING
+Command to send the password to via standard input.
+.TP
+.BI \-\-prompt= STRING
+Message to display when asking for the password.
+.TP
+.BI \-\-number-of-tries= INTEGER
+Number of times to ask before giving up (requires \fB\-\-command\fR).
+.TP
+.B \-\-dont-pause-progress
+Silently ignored by \fBblogctl\fR (provided for plymouth compatibility).
+.RE
+.TP
+.B ask-question
+Ask the user a question on the system console.
+.RS
+.TP
+.BI \-\-command= STRING
+Command to send the answer to via standard input.
+.TP
+.BI \-\-prompt= STRING
+Message to display when asking the question.
+.TP
+.B \-\-dont-pause-progress
+Silently ignored by \fBblogctl\fR.
+.RE
+.TP
+.B display-message
+Display a message. \fBblogd\fR prints this message to all active hardware 
+consoles and injects it into the boot log stream.
+.RS
+.TP
+.BI \-\-text= STRING
+The message text to display.
+.RE
+.TP
+.B hide-message
+Hide a message. 
+.RS
+.TP
+.BI \-\-text= STRING
+The message text to hide. Note: \fBblogd\fR intentionally ignores the visual 
+clearing of messages to prevent screen corruption and preserve the scroll 
+buffer on line-based hardware consoles (like s390x 3215).
+.RE
+.TP
 .B ping
 Send a simply ping request if
 .B blogd
 daemon is up and running.
 .TP
-.B quit
+.B quit \fR[\fB\-\-wait\fR]
 Cause the
 .B blogd
-daemon to finish its logging and then gracefully quits.
+daemon to finish its logging and then gracefully quits.  If the optional
+\fB\-\-wait\fR flag is specified, \fBblogctl\fR will block and wait 
+until the daemon has fully flushed the logs and closed the connection.
 .TP
 .BI root= <path>
 This command take a path as further value of the new root file
@@ -65,7 +117,8 @@
 .BR blogd (8),
 .BR systemd (1),
 .SH COPYRIGHT
-2015 Werner Fink,
-2015 SuSE Linux GmbH.
+2015,2026 Werner Fink,
+2015 SUSE Linux GmbH,
+2026 SUSE Software Solutions Germany GmbH.
 .SH AUTHOR
 Werner Fink <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/blogctl.c 
new/showconsole-2.46/blogctl.c
--- old/showconsole-2.45/blogctl.c      2026-07-02 11:25:23.000000000 +0200
+++ new/showconsole-2.46/blogctl.c      2026-07-09 15:29:51.000000000 +0200
@@ -9,11 +9,16 @@
  * (at your option) any later version.
  */
 
+#include <endian.h>    /* For le32toh */
 #include <err.h>
+#include <getopt.h>
 #include <limits.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <poll.h>
+#include <sys/socket.h>
 #include "libconsole.h"
 
 /*
@@ -45,6 +50,10 @@
     } cmds[] = {
        { "root=",              MAGIC_CHROOT,           1, NULL },      /* New 
root */
        { "ping",               MAGIC_PING,             0, NULL },      /* Ping 
*/
+       { "ask-for-password",   MAGIC_ASK_PWD,          0, NULL },
+       { "ask-question",       MAGIC_QUESTION,         0, NULL },
+       { "display-message",    MAGIC_SHOW_MSG,         0, NULL },
+       { "hide-message",       MAGIC_HIDE_MSG,         0, NULL },
        { "ready",              MAGIC_SYS_INIT,         0, NULL },      /* 
System ready */
        { "quit",               MAGIC_QUIT,             0, NULL },      /* Quit 
*/
        { "final",              MAGIC_FINAL,            0, NULL },      /* 
Final */
@@ -80,11 +89,37 @@
     return ret;
 }
 
+static int wait_for_blogd_close(int fd)
+{
+     struct pollfd pfd;
+     pfd.fd = fd;
+     pfd.events = POLLIN|POLLRDHUP;
+     pfd.revents = 0;
+ 
+     while (1) {
+        int ret = poll(&pfd, 1, -1);
+ 
+        if (ret < 0) {
+            if (errno == EINTR)
+                continue;
+            return -1;
+        }
+ 
+        if (pfd.revents & (POLLHUP|POLLRDHUP|POLLIN)) {
+            char buf[1];
+            /* Verify if socket is really down (EOF = 0 bytes) */
+            int n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
+            if (n == 0 || (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK))
+                return 0;       /* down */
+        }
+     }
+}
+
 int main(int argc, char *argv[])
 {
     char *root = NULL;
     char *message, answer[2], cmd[2];
-    int fdsock = -1, ret, len;
+    int fdsock = -1, ret, len, do_wait = 0;
 
     cmd[1] = '\0';
     answer[0] = '\x15';
@@ -94,7 +129,7 @@
        error("no blogd active");
 
     while ((cmd[0] = getcmd(argc, argv)) != (char)-1) {
-        switch (cmd[0]) {
+       switch (cmd[0]) {
        case MAGIC_CHROOT:
            root = optarg;
            len = (int)strlen(root);
@@ -112,21 +147,162 @@
        case MAGIC_PING:
        case MAGIC_SYS_INIT:
        case MAGIC_QUIT:
+           /* Check if --wait was passed as an argument to quit */
+           if (cmd[0] == MAGIC_QUIT && argv[optind] && strcmp(argv[optind], 
"--wait") == 0) {
+               do_wait = 1;
+               optind++; /* Consume the argument so getcmd doesn't trip over 
it */
+           }
        case MAGIC_FINAL:
        case MAGIC_CLOSE:
        case MAGIC_DEACTIVATE:
        case MAGIC_REACTIVATE:
            safeout(fdsock, cmd, strlen(cmd)+1, SSIZE_MAX);
            break;
+       case MAGIC_ASK_PWD:
+       case MAGIC_QUESTION: {
+           char *prompt = NULL;
+           char *command = NULL;
+           int c, tries = 1;
+
+           /* Parse the parameters */
+           static struct option long_options[] = {
+               {"prompt",              required_argument, 0, 'p'},
+               {"command",             required_argument, 0, 'c'},
+               {"number-of-tries",     required_argument, 0, 'n'},
+               {"dont-pause-progress", no_argument,       0, 'd'},
+               {0, 0, 0, 0}
+           };
+
+           /* * getopt_long_only parst ab argv[optind]. Da wir getcmd()
+            * benutzt haben, steht optind genau richtig auf der ersten Option.
+            */
+           while ((c = getopt_long_only(argc, argv, "", long_options, NULL)) 
!= -1) {
+               switch (c) {
+                   case 'p':
+                       prompt = optarg;
+                       break;
+                   case 'c':
+                       command = optarg;
+                       break;
+                   case 'n':
+                       tries = atoi(optarg);
+                       break;
+                   case 'd':
+                       /* Ignored by blogd as it is useless  */
+                       break;
+                   case '?':
+                   default:
+                       break;
+               }
+           }
+
+           if (!prompt)
+               prompt = (cmd[0] == MAGIC_ASK_PWD) ? "Password" : "Question";
+
+           len = (int)strlen(prompt);
+           if (len >= UCHAR_MAX) {
+               errno = EINVAL;
+               error("prompt string too long (max 254 chars)");
+           }
+
+           do {
+               message = NULL;
+               ret = asprintf(&message, "%c\002%c%s%n", cmd[0], len + 1, 
prompt, &len);
+               if (ret < 0)
+                   error("can not allocate message");
+               
+               safeout(fdsock, message, len + 1, SSIZE_MAX);
+               free(message);
+
+               /* Wait for the users answer */
+               if (can_read(fdsock, -1)) {
+                   char ans;
+                   safein(fdsock, &ans, 1);
+
+                   if (ans == '\t') {                  /* ANSWER_MLT */
+                       uint32_t plen;
+                       safein(fdsock, &plen, sizeof(plen));
+                       plen = le32toh(plen);   /* Plymouth sends le32 */
+
+                       char *pwd = calloc(1, plen + 1);
+                       if (!pwd)
+                           error("memory allocation failed");
+                           
+                       safein(fdsock, pwd, plen);
+
+                       if (command) {
+                           FILE *p = popen(command, "w");
+                           if (p) {
+                               fputs(pwd, p);
+                               if (pclose(p) == 0) {
+                                   free(pwd);
+                                   answer[0] = '\x6';  /* Fake ACK for success 
*/
+                                   goto end_cmd;
+                               }
+                           }
+                       } else {
+                           printf("%s\n", pwd);
+                           free(pwd);
+                           answer[0] = '\x6';          /* Fake ACK for success 
*/
+                           goto end_cmd;
+                       }
+                       free(pwd);
+                   } else if (ans == '\x5') { 
+                       /* ANSWER_ENQ: Cancel / No input */
+                       break;
+                   }
+               }
+               tries--;
+           } while (tries > 0);
+
+           /* If we end up here, all attempts have failed */
+           answer[0] = '\x15';                         /* NACK */
+           goto end_cmd;
+       }
+       case MAGIC_SHOW_MSG:
+       case MAGIC_HIDE_MSG: {
+           char *text = "";
+           int c;
+
+           static struct option long_options[] = {
+               {"text", required_argument, 0, 't'},
+               {0, 0, 0, 0}
+           };
+
+           while ((c = getopt_long_only(argc, argv, "", long_options, NULL)) 
!= -1) {
+               if (c == 't')
+                   text = optarg;
+           }
+
+           len = (int)strlen(text);
+           if (len >= UCHAR_MAX) {
+               errno = EINVAL;
+               error("message string too long (max 254 chars)");
+           }
+
+           message = NULL;
+           ret = asprintf(&message, "%c\002%c%s%n", cmd[0], len + 1, text, 
&len);
+           if (ret < 0)
+               error("can not allocate message");
+           
+           safeout(fdsock, message, len + 1, SSIZE_MAX);
+           free(message);
+           
+           break;
+       }
        case '?':
        default:
            goto fail;
-        }
+       }
 
        if (can_read(fdsock, 1000)) {
            answer[0] = '\0';
            safein(fdsock, &answer[0], sizeof(answer));
        }
+end_cmd:
+       /* If we received an ACK (0x06) and --wait was requested, block until 
closed */
+       if (do_wait && answer[0] == '\x6')
+           wait_for_blogd_close(fdsock);
 
        break;          /* One command per call only */
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/blogd.c new/showconsole-2.46/blogd.c
--- old/showconsole-2.45/blogd.c        2026-07-02 11:25:23.000000000 +0200
+++ new/showconsole-2.46/blogd.c        2026-07-09 15:29:51.000000000 +0200
@@ -169,11 +169,12 @@
 static struct sigaction saved_sigttou;
 static struct sigaction saved_sigtstp;
 static struct sigaction saved_sighup;
+static struct sigaction saved_sigpipe;
+#ifdef NO_SIGNALFD
 static struct sigaction saved_sigint;
 static struct sigaction saved_sigquit;
 static struct sigaction saved_sigterm;
 static struct sigaction saved_sigsys;
-static struct sigaction saved_sigpipe;
 
 static void sighandle(int sig)
 {
@@ -189,6 +190,7 @@
 {
     nsigsys = (volatile sig_atomic_t)sig;
 }
+#endif
 
 /*
  * To be able to reconnect to real tty on EIO
@@ -289,12 +291,12 @@
     parse_cmdline();   /* Parse the kernel command line for blog.<key>(=<val>) 
*/
     val = value_cmdline("silent");
     if (val) {
-        if (strcmp(val, "1") == 0 || strcasecmp(val, "on") == 0 || 
strcasecmp(val, "yes") == 0 || strcasecmp(val, "true"))
+        if (strcmp(val, "1") == 0 || strcasecmp(val, "on") == 0 || 
strcasecmp(val, "yes") == 0 || strcasecmp(val, "true") == 0)
             console_silent = 1;
     }
     val = value_cmdline("coldboot");
     if (val) {
-        if (strcmp(val, "1") == 0 || strcasecmp(val, "on") == 0 || 
strcasecmp(val, "yes") == 0 || strcasecmp(val, "true"))
+        if (strcmp(val, "1") == 0 || strcasecmp(val, "on") == 0 || 
strcasecmp(val, "yes") == 0 || strcasecmp(val, "true") == 0)
             coldboot = 1;
     }
 
@@ -424,6 +426,7 @@
     set_signal(SIGTSTP, &saved_sigtstp, SIG_IGN);
     set_signal(SIGHUP,  &saved_sighup,  SIG_IGN);
     set_signal(SIGPIPE, &saved_sigpipe, SIG_IGN);
+#ifdef NO_SIGNALFD
     set_signal(SIGINT,  &saved_sigint,  sighandle);
     set_signal(SIGQUIT, &saved_sigquit, sighandle);
     set_signal(SIGTERM, &saved_sigterm, sighandle);
@@ -432,6 +435,7 @@
     (void)restart_sig(SIGQUIT, 1);
     (void)restart_sig(SIGTERM, 1);
     (void)restart_sig(SIGSYS,  1);
+#endif
 
     list_for_each_entry(c, &lcons, node) {
        struct termios oldtio;
@@ -654,10 +658,12 @@
     reset_signal(SIGTSTP, &saved_sigtstp);
     reset_signal(SIGHUP,  &saved_sighup);
     reset_signal(SIGPIPE, &saved_sigpipe);
+#ifdef NO_SIGNALFD
     reset_signal(SIGINT,  &saved_sigint);
     reset_signal(SIGQUIT, &saved_sigquit);
     reset_signal(SIGTERM, &saved_sigterm);
     reset_signal(SIGSYS,  &saved_sigsys);
+#endif
 }
 
 #if defined(__s390__) || defined(__s390x__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/coldstart.c 
new/showconsole-2.46/libconsole/coldstart.c
--- old/showconsole-2.45/libconsole/coldstart.c 2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/coldstart.c 2026-07-09 15:29:51.000000000 
+0200
@@ -32,8 +32,9 @@
 void send_response_to_systemd(const char *socket_path, const char *password)
 {
     char *packet;
-    size_t pwd_len, packet_len;
+    size_t pwd_len, packet_len, sock_len;
     struct sockaddr_un addr;
+    ssize_t sent;
 
     int sock = socket(AF_UNIX, SOCK_DGRAM, 0);
     if (sock < 0)
@@ -41,13 +42,19 @@
 
     memset(&addr, 0, sizeof(addr));
     addr.sun_family = AF_UNIX;
-    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
+
+    sock_len = strlen(socket_path);
+    if (sock_len >= sizeof(addr.sun_path)) {
+       warn("systemd ask-password socket path too long: %s", socket_path);
+       close(sock);
+       return;
+    }
+    memcpy(addr.sun_path, socket_path, sock_len + 1);
 
     /* systemd protocol requires: '+' + password (the \0 is optional) */
     pwd_len = strlen(password);
     packet_len = pwd_len + 1; /* +1 for '+' */
     packet = (char*)malloc(packet_len);
-
     if (!packet)
        error("memory allocation: %m");
 
@@ -55,7 +62,9 @@
     memcpy(packet + 1, password, pwd_len);
 
     /* Now send the packet as one datagramm (SOCK_DGRAM) */
-    sendto(sock, packet, packet_len, 0, (struct sockaddr *)&addr, 
sizeof(addr));
+    sent = sendto(sock, packet, packet_len, 0, (struct sockaddr *)&addr, 
sizeof(addr));
+    if (sent < 0 || (size_t)sent != packet_len)
+       warn("failed to send password reply to %s: %m", socket_path);
 
     free(packet);
     close(sock);
@@ -105,11 +114,11 @@
     in_ask_section = 0;
 
     /* Allocate memory for our custom wrapper structure */
-    if (posix_memalign((void**)&req, sizeof(void*), ALIGNED_SIZEOF(struct 
request)) != 0 || !req) {
+    if (posix_memalign((void**)&req, sizeof(void*), align_up(struct request, 
void*)) != 0 || !req) {
        fclose(fp);
        error("memory allocation: %m");
     }
-    memset(req, 0, sizeof(struct request));
+    memset(req, 0, align_up(struct request, void*));
 
     while (fgets(line, sizeof(line), fp)) {
        char *eq, *key, *value;
@@ -175,8 +184,13 @@
     char full_path[MAX_LINE];
 
     DIR *dir = opendir(dir_path);
-    if (!dir)
-       error("Failed to open systemd ask-password directory: %m");
+    if (!dir) {
+        if (errno == ENOENT)
+           warn("systemd ask-password directory %s not available", dir_path);
+        else    
+           error("Failed to open systemd ask-password directory %s: %m", 
dir_path);
+       return;
+    }
 
     while ((entry = readdir(dir)) != NULL) {
        if (entry->d_name[0] == '.')
@@ -230,3 +244,19 @@
 
     return 1;
 }
+
+void coldstart_free_requests(void)
+{
+    struct request *req, *next;
+
+    list_for_each_entry_safe(req, next, &pwd_requests, node) {
+       if (req->message)
+           free(req->message);
+       if (req->socket_path)
+           free(req->socket_path);
+       delete(&req->node);
+       free(req);
+    }
+
+    requests = NULL;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/console.c 
new/showconsole-2.46/libconsole/console.c
--- old/showconsole-2.45/libconsole/console.c   2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/console.c   2026-07-09 15:29:51.000000000 
+0200
@@ -43,6 +43,8 @@
 #include "listing.h"
 #include "libconsole.h"
 
+weak_symbol(pthread_sigmask);
+
 /* Fallback for older glibc */
 
 #ifndef SYS_pidfd_open
@@ -91,6 +93,7 @@
  * Password/Passphrase is asked if true.
  */
 volatile sig_atomic_t asking;
+static int ask_mode = 1;       /* 1 = Password, 2 = Question */
 
 /*
  * Ths is the socket fd for the answer.
@@ -157,10 +160,12 @@
        } error(fmt, args);         \
     } while (0)
 
-static volatile sig_atomic_t sigchild;
+volatile sig_atomic_t sigchild;
+#ifdef NO_SIGNALFD
 static void chld_handler(int sig) {
     ++sigchild;
 }
+#endif
 
 /*
  * Console list
@@ -493,8 +498,9 @@
  * Signal control for writing on log file
  */
 volatile sig_atomic_t nsigsys;
-static volatile sig_atomic_t nsigio = -1;
+volatile sig_atomic_t nsigio = -1;
 
+#ifdef NO_SIGNALFD
 /* One shot signal handler */
 static void sigio(int sig)
 {
@@ -503,6 +509,7 @@
        set_signal(sig, NULL, SIG_IGN);
     nsigio = sig;
 }
+#endif
 
 /*
  * Our transfer buffer from system console to the devices
@@ -568,13 +575,34 @@
 void prepareIO(int (*rfunc)(int), const int listen, const int input)
 {
     struct console *c;
+#ifndef NO_SIGNALFD
+    sigset_t sfd_mask;
+
+    sigemptyset(&sfd_mask);
+    sigaddset(&sfd_mask, SIGINT);
+    sigaddset(&sfd_mask, SIGQUIT);
+    sigaddset(&sfd_mask, SIGTERM);
+    sigaddset(&sfd_mask, SIGSYS);
+    sigaddset(&sfd_mask, SIGIO);
+    sigaddset(&sfd_mask, SIGCHLD);
+#endif
+
+    epfd = epoll_create1(EPOLL_CLOEXEC);
+    if (epfd < 0)
+       error("can not open epoll file descriptor");
+
+#ifndef NO_SIGNALFD
+    /* Block signals globally and register the file descriptor to epoll */
+    setup_signalfd(sfd_mask);
+#endif
 
     (void)sigfillset(&omask);
+#ifdef NO_SIGNALFD
     (void)sigdelset(&omask, SIGQUIT);
     (void)sigdelset(&omask, SIGTERM);
     (void)sigdelset(&omask, SIGSYS);
     (void)sigdelset(&omask, SIGIO);
-
+#endif
     vc_reconnect = rfunc;
     fdsock  = listen;                  /* We use only ONE socket ... see also 
safeout() */
     fdread  = input;
@@ -595,10 +623,6 @@
        }
     }
 
-    epfd = epoll_create1(EPOLL_CLOEXEC);
-    if (epfd < 0)
-       error("can not open epoll file descriptor");
-
     if (fdread >= 0)
        epoll_addread(fdread, &epoll_console_in);
     if (fdfifo >= 0)
@@ -778,8 +802,9 @@
        /* Currently no thread active */
        nsigio = 0;
        atboot = 1;
-
+#ifdef NO_SIGNALFD
        set_signal(SIGIO, NULL, sigio);
+#endif
     }
 
     if (flog) {
@@ -805,7 +830,9 @@
        }
        if (nsigio < 0) {
            nsigio = SIGIO;
+#ifdef NO_SIGNALFD
            (void)set_signal(SIGIO, NULL, SIG_IGN);
+#endif
        }
     }
 }
@@ -881,6 +908,8 @@
        pwprompt = NULL;
     }
 
+    coldstart_free_requests();
+
     list_for_each_entry(c, &lcons, node) {
        if (c->fd < 0)
            continue;
@@ -948,10 +977,10 @@
     if (!cons)
        error("missing console pointer");
 
-    if (posix_memalign((void**)&newc, sizeof(void*), ALIGNED_SIZEOF(struct 
console)+strlen(name)+1) != 0 || !newc)
+    if (posix_memalign((void**)&newc, sizeof(void*), align_up(struct console, 
void*)+strlen(name)+1) != 0 || !newc)
        error("memory allocation");
 
-    newc->tty = ((char*)newc)+ALIGNED_SIZEOF(struct console);
+    newc->tty = ((char*)newc)+align_up(struct console, void*);
     strcpy(newc->tty, name);
     newc->flags = cflags;
     newc->dev = dev;
@@ -1051,6 +1080,8 @@
            flags |= CON_SCLP;
        else if (maj == 227 && min >= 1)
            flags |= CON_3270;
+       else if (maj == 229 && min >= 0)
+           flags |= CON_HVC;
 #endif
        consalloc(&c, tty, flags, makedev(maj, min), io);
        free(tty);
@@ -1445,6 +1476,7 @@
 
     switch (magic[0]) {
     case MAGIC_ASK_PWD:
+    case MAGIC_QUESTION:
        if (magic[1] != '\002') {
            errno = EINVAL;
            warn("Got password invalid request for prompt");
@@ -1463,6 +1495,7 @@
            if (pwprompt)
                free(pwprompt);
            pwprompt = strdup(arg);
+           ask_mode = (magic[0] == MAGIC_QUESTION) ? 2 : 1;
 
            epoll_answer_once(fd, &epoll_socket_answer);
            goto job;
@@ -1477,6 +1510,7 @@
        }
        password[0] = '\0';
        pwprompt = strdup(arg);
+       ask_mode = (magic[0] == MAGIC_QUESTION) ? 2 : 1;
 
        epoll_answer_once(fd, &epoll_socket_answer);
 
@@ -1493,9 +1527,11 @@
        break;
 
     case MAGIC_CHROOT:
-       if (magic[1] != '\002') {
+       if (magic[1] != '\002' || !arg || !*arg || arg[0] != '/') {
            errno = EINVAL;
            warn("Got password invalid chroot request");
+           enqry = ANSWER_NCK;
+           safeout(fd, enqry, strlen(enqry)+1, SSIZE_MAX);
            goto out;
        }
 
@@ -1510,9 +1546,10 @@
 
        enqry = ANSWER_ACK;
        safeout(fd, enqry, strlen(enqry)+1, SSIZE_MAX);
-
+#ifdef NO_SIGNALFD
        if (nsigio == 0)
            set_signal(SIGIO, NULL, SIG_IGN);
+#endif
        nsigio = SIGIO;
 
        break;
@@ -1667,13 +1704,54 @@
 
        enqry = ANSWER_ACK;
        safeout(fd, enqry, strlen(enqry)+1, SSIZE_MAX);
-
+#ifdef NO_SIGNALFD
        if (nsigsys == 0)
            set_signal(SIGSYS, NULL, SIG_IGN);
+#endif
        nsigsys = SIGSYS;
 
        break;
 
+    case MAGIC_SHOW_MSG:
+       if (magic[1] != '\002' || !arg) {
+           errno = EINVAL;
+           enqry = ANSWER_NCK;
+           safeout(fd, enqry, strlen(enqry)+1, SSIZE_MAX);
+           goto out;
+       }
+       if (*arg) {
+           char *logmsg;
+           int l = asprintf(&logmsg, "\n*** MESSAGE: %s ***\n", arg);
+           if (l > 0) {
+               struct console *c;
+
+               /* 1. Write to /var/log/boot.log */
+               copylog(logmsg, l);
+               flushlog();
+
+               /* 2. Write to all active physical screens */
+               list_for_each_entry(c, &lcons, node) {
+                   if (c->fd < 0 || FD_ISSET(c->fd, &blocked))
+                       continue;
+                   if (!console_silent)
+                       c->out(c->fd, logmsg, l, c->max_canon);
+               }
+               free(logmsg);
+           }
+       }
+       enqry = ANSWER_ACK;
+       safeout(fd, enqry, strlen(enqry)+1, SSIZE_MAX);
+       break;
+
+    case MAGIC_HIDE_MSG:
+       /* * No-Op for the screen. We intentionally ignore the text payload 
+        * because line-based consoles (like s390x 3215) cannot clear lines.
+        * We just acknowledge the command.
+        */
+       enqry = ANSWER_ACK;
+       safeout(fd, enqry, strlen(enqry)+1, SSIZE_MAX);
+       break;
+
     default:
 
        enqry = ANSWER_NCK;
@@ -1723,9 +1801,10 @@
        pwprompt[len] = '\0';
        len--;
     }
+#ifdef NO_SIGNALFD
     set_signal(SIGCHLD, NULL, chld_handler);
-
-    asking = 1;                                /* Show only our question about 
password/passphrase */
+#endif
+    asking = ask_mode;                 /* Show only our question about 
password/passphrase */
 
     /* pwprompt */
     list_for_each_entry(c, &lcons, node) {
@@ -1747,6 +1826,14 @@
 #if defined(__s390__) || defined(__s390x__)
            int vmcpfd = -1;
 #endif
+#ifndef NO_SIGNALFD
+           sigset_t empty_mask;
+           sigemptyset(&empty_mask);
+           if ((pthread_sigmask))
+               pthread_sigmask(SIG_UNBLOCK, &empty_mask, NULL);
+           else
+               sigprocmask(SIG_SETMASK, &empty_mask, NULL);
+#endif
            if (fdfifo >= 0)
                close(fdfifo);
            if (fdsock >= 0)
@@ -1840,7 +1927,7 @@
                 * and blocks the subsequent readpw() call forever.
                 */
                len = asprintf(&message, "\n===>> %s:\n", pwprompt);
-           } else if (c->flags & (CON_SCLP|CON_3270)) {
+           } else if (c->flags & (CON_SCLP|CON_3270|CON_HVC)) {
                /*
                 * The 3270 console can do ANSI colouring and carriage returns,
                 * as well as the sclp consoles which are a full featured ttys.
@@ -1889,17 +1976,24 @@
            /* We read byte for byte */
            newtio = c->ctio;
 #if defined(__s390__) || defined(__s390x__)
-           if (c->flags & CON_3270)
-               /*
-                * ONLY the 3270 block-mode terminal MUST keep ICANON enabled!
-                * Otherwise the tty3270 driver switches to raw mode and fails
-                * to apply the non-display hardware attribute to the input 
field.
-                */
-               newtio.c_lflag &= ~(ECHO);
-           else
-               newtio.c_lflag &= ~(ECHO|ICANON);
+           if (asking == 2) {
+               newtio.c_lflag = (newtio.c_lflag | ECHO) & ~ICANON;
+           } else {
+               if (c->flags & CON_3270)
+                   /*
+                   * ONLY the 3270 block-mode terminal MUST keep ICANON 
enabled!
+                   * Otherwise the tty3270 driver switches to raw mode and 
fails
+                   * to apply the non-display hardware attribute to the input 
field.
+                   */
+                   newtio.c_lflag &= ~(ECHO);
+               else
+                   newtio.c_lflag &= ~(ECHO|ICANON);
+           }
 #else
-           newtio.c_lflag &= ~(ECHO|ICANON);
+           if (asking == 2)
+               newtio.c_lflag = (newtio.c_lflag | ECHO) & ~ICANON;
+           else
+               newtio.c_lflag &= ~(ECHO|ICANON);
 #endif
            newtio.c_lflag |= ECHONL;
            newtio.c_cc[VTIME] = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/epoll.c 
new/showconsole-2.46/libconsole/epoll.c
--- old/showconsole-2.45/libconsole/epoll.c     2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/epoll.c     2026-07-09 15:29:51.000000000 
+0200
@@ -40,7 +40,7 @@
 
     ev.events = flags;
 
-    if (posix_memalign((void**)&ep, sizeof(void*), ALIGNED_SIZEOF(struct 
epolls)) != 0 || !ep)
+    if (posix_memalign((void**)&ep, sizeof(void*), align_up(struct epolls, 
void*)) != 0 || !ep)
        error("memory allocation");
 
     ep->handle = (typeof(ep->handle))fptr;
@@ -87,7 +87,7 @@
     if (!target) {
        list_t *head;
 
-       if (posix_memalign((void**)&ep, sizeof(void*), ALIGNED_SIZEOF(struct 
epolls)) != 0 || !ep)
+       if (posix_memalign((void**)&ep, sizeof(void*), align_up(struct epolls, 
void*)) != 0 || !ep)
            error("memory allocation");
 
        ep->fd = fd;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/frobnicate.c 
new/showconsole-2.46/libconsole/frobnicate.c
--- old/showconsole-2.45/libconsole/frobnicate.c        2026-07-02 
11:25:23.000000000 +0200
+++ new/showconsole-2.46/libconsole/frobnicate.c        2026-07-09 
15:29:51.000000000 +0200
@@ -1,6 +1,10 @@
 /*
  * frobnicate.c
  *
+ * In-memory reversible obfuscation for cached passwords.
+ * This is not cryptographic protection against a memory-reading attacker.
+ * It is only meant to avoid trivial/plaintext exposure in memory.
+ *
  * Copyright 2015 Werner Fink, 2015 SuSE Linux GmbH.
  *
  * This source is free software; you can redistribute it and/or modify
@@ -12,29 +16,72 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/random.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <unistd.h>
 
-static unsigned char randnum;
+#define FROBMASK_LEN   32
+
+static unsigned char frobmask[FROBMASK_LEN];
+
 static void initialseed(void) __attribute__((__constructor__));
 static void initialseed(void)
 {
-    struct timeval tv;
-    gettimeofday (&tv, NULL);
-    srand (tv.tv_sec ^ tv.tv_usec ^ getpid());
-    randnum = (unsigned char)(rand() & 0xff);
-    if (!randnum)
-       randnum = 42;
+    size_t off = 0;
+ 
+    while (off < sizeof(frobmask)) {
+       ssize_t ret = getrandom(frobmask+off, sizeof(frobmask)-off, 
GRND_NONBLOCK);
+       if (ret < 0) {
+           if (errno == EINTR)
+               continue;
+           break;
+       }
+       if (ret == 0)
+           break;
+       off += (size_t)ret;
+    }
+ 
+    if (off == sizeof(frobmask))
+       return;
+
+    /*
+     * Early-boot fallback:
+     * weak but stable for the process lifetime and inherited across fork().
+     */
+    {
+       struct timeval tv;
+       unsigned int seed;
+       size_t pos;
+
+       gettimeofday(&tv, NULL);
+       seed = (unsigned int)(tv.tv_sec ^ tv.tv_usec ^ getpid());
+ 
+       for (pos = 0; pos < sizeof(frobmask); pos++) {
+           seed = seed * 1103515245u + 12345u;
+           frobmask[pos] = (unsigned char)((seed >> 16) & 0xff);
+       }
+ 
+       /* Avoid an all-zero mask, just in case */
+       for (pos = 0; pos < sizeof(frobmask); pos++) {
+           if (frobmask[pos] != 0)
+               return;
+       }
+
+       frobmask[0] = 42;
+    }
 }
 
 void *frobnicate(void *in, const size_t len)
 {
     unsigned char *ptr = (unsigned char *)in;
-    ssize_t pos = len;
+    size_t pos;
+
+    if (!ptr || len == 0)
+       return in;
 
-    while (pos-- > 0)
-       *ptr++ ^= randnum;
+    for (pos = 0; pos < len; pos++)
+       ptr[pos] ^= frobmask[pos % FROBMASK_LEN];
 
     return in;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/libconsole.h 
new/showconsole-2.46/libconsole/libconsole.h
--- old/showconsole-2.45/libconsole/libconsole.h        2026-07-02 
11:25:23.000000000 +0200
+++ new/showconsole-2.46/libconsole/libconsole.h        2026-07-09 
15:29:51.000000000 +0200
@@ -11,6 +11,7 @@
 
 #include <err.h>
 #include <errno.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <signal.h>
 #include <sys/types.h>
@@ -49,7 +50,7 @@
 #endif
 #include "listing.h"
 
-#define ALIGNED_SIZEOF(type)           ((sizeof(type)+(sizeof(void*)-1)) & 
~(sizeof(void*)-1))
+#define align_up(type,boundary)        ((sizeof(type)+(sizeof(boundary)-1)) & 
~(sizeof(boundary)-1))
 #define strsize(string)                ((strlen(string)+1)*sizeof(char))
 
 #if defined __USE_ISOC99
@@ -121,6 +122,7 @@
 #define CON_3215       (128)   /* s390x 3215 halfduplex console */
 #define CON_3270       (256)   /* s390x 3270 console */
 #define CON_SCLP       (512)   /* s390x sclp terminals */
+#define CON_HVC                (1024)  /* s390x hvc terminals */
 
 extern sigset_t omask;
 extern int final;
@@ -129,7 +131,9 @@
 extern int epfd;
 extern int evmax;
 extern volatile sig_atomic_t signaled;
+extern volatile sig_atomic_t sigchild;
 extern volatile sig_atomic_t nsigsys;
+extern volatile sig_atomic_t nsigio;
 extern volatile sig_atomic_t asking;
 
 extern void remember_arg0(volatile char *arg0);
@@ -151,6 +155,7 @@
 extern void scan_ask_directory(const char *dir_path);
 extern void send_response_to_systemd(const char *socket_path, const char 
*password);
 extern int coldstart_pop_request(char **message, char **socket_path);
+extern void coldstart_free_requests(void);
 
 /* devices.c */
 extern char *charname(const char *dev);
@@ -206,6 +211,9 @@
 extern void set_signal(int sig, struct sigaction *old, sighandler_t handler);
 extern void reset_signal(int sig, struct sigaction *old);
 extern int restart_sig(int sig, int flag);
+#ifndef NO_SIGNALFD
+extern int setup_signalfd(sigset_t mask);
+#endif
 
 /* socket.c */
 extern int open_un_socket_and_listen(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/proc.c 
new/showconsole-2.46/libconsole/proc.c
--- old/showconsole-2.45/libconsole/proc.c      2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/proc.c      2026-07-09 15:29:51.000000000 
+0200
@@ -58,6 +58,7 @@
     dir = opendir(fds);
     if (!dir) {
        warn("can not open %s", fds);
+       free(fds);
        return;
     }
     free(fds);
@@ -140,9 +141,9 @@
                        }
                    }
                    if (!exists) {
-                       if (posix_memalign((void**)&pm, sizeof(void*), 
ALIGNED_SIZEOF(parameter_t)+strlen(key)+1) != 0 || !pm)
+                       if (posix_memalign((void**)&pm, sizeof(void*), 
align_up(parameter_t, void*) + strlen(key)+1) != 0 || !pm)
                            error("memory allocation");
-                       pm->key = ((char*)pm)+ALIGNED_SIZEOF(parameter_t);
+                       pm->key = ((char*)pm)+align_up(parameter_t, void*);
                        strcpy(pm->key, key);
                        pm->val = strdup(val);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/shm.c 
new/showconsole-2.46/libconsole/shm.c
--- old/showconsole-2.45/libconsole/shm.c       2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/shm.c       2026-07-09 15:29:51.000000000 
+0200
@@ -101,6 +101,9 @@
     if (area == MAP_FAILED)
         error("can not map shared memory object into memory");
 
+    if (shmfd >= 0)
+       close(shmfd);
+
     if (devshm) {
        /* shm_ */ unlink(template);
        free(template);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/signals.c 
new/showconsole-2.46/libconsole/signals.c
--- old/showconsole-2.45/libconsole/signals.c   2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/signals.c   2026-07-09 15:29:51.000000000 
+0200
@@ -12,6 +12,10 @@
 #include <errno.h>
 #include <stddef.h>
 #include <signal.h>
+#ifndef NO_SIGNALFD
+# include <sys/signalfd.h>
+# include <string.h>
+#endif
 #include "libconsole.h"
 
 weak_symbol(pthread_sigmask);
@@ -90,3 +94,63 @@
 
     return ret;
 }
+
+#ifndef NO_SIGNALFD
+/* Part of signal handling with signalfd only valid for libconsole */
+
+static void handle_signal_event(int fd)
+{
+    struct signalfd_siginfo fdsi;
+
+    ssize_t s = read(fd, &fdsi, sizeof(struct signalfd_siginfo));
+    if (s != sizeof(struct signalfd_siginfo))
+       return;         /* Short reads are impossible by kernel design.
+                          Catching -1 (e.g. EAGAIN) here. */
+
+    switch (fdsi.ssi_signo) {
+    case SIGTERM:
+    case SIGQUIT:
+    case SIGINT:
+       if (nsigsys && (fdsi.ssi_signo == SIGTERM))
+           break;
+       signaled = fdsi.ssi_signo;
+       break;
+    case SIGSYS:
+       nsigsys = SIGSYS;
+       break;
+    case SIGIO:
+       nsigio = SIGIO;
+       break;
+    case SIGCHLD:
+       sigchild++;
+       break;
+    default:
+       warn("Signal catched %s but not handled", strsignal(fdsi.ssi_signo));
+       break;
+    }
+}
+
+int setup_signalfd(sigset_t mask)
+{
+    int sfd = -1;
+
+    if ((pthread_sigmask))
+       pthread_sigmask(SIG_BLOCK, &mask, NULL);
+    else
+       sigprocmask(SIG_BLOCK, &mask, NULL);
+
+    /*
+     * The SFD_NONBLOCK is essential for (e)polling
+     * whereas SFD_CLOEXEC we might not need.
+     * Nevertheless how to handle the logging thread
+     * as well as the forking password questioners
+     */
+    sfd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+    if (sfd < 0)
+       error("can not open signal file descriptor");
+
+    epoll_addread(sfd, &handle_signal_event);
+
+    return sfd;
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/tty.c 
new/showconsole-2.46/libconsole/tty.c
--- old/showconsole-2.45/libconsole/tty.c       2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/tty.c       2026-07-09 15:29:51.000000000 
+0200
@@ -52,7 +52,7 @@
 int request_tty(const char *tty)
 {
     struct sigaction saved_sighup;
-    int fd = -1, nd, wd;
+    int fd = -1, nd, wd = -1;
 #if defined(__s390__) || defined(__s390x__)
     struct stat sb;
 #endif
@@ -74,12 +74,13 @@
     wd = inotify_add_watch(nd, tty, IN_CLOSE);
     if (wd < 0) {
        warn("can not add a watch on inotifier %d for %s", nd, tty);
+       close(nd);
        return -1;
     }
 
     do {
        ssize_t len;
-       int ret, flags;
+       int ret, flags, got_close = 0;
 
        clear_input(nd);
 
@@ -89,7 +90,7 @@
            break;
        }
 
-       set_signal(SIGHUP, NULL, SIG_IGN);
+       set_signal(SIGHUP, &saved_sighup, SIG_IGN);
        ret = ioctl(fd, TIOCSCTTY, 0);
        reset_signal(SIGHUP, &saved_sighup);
 
@@ -113,8 +114,8 @@
        if (ret >= 0)
            break;      /* Success */
 
-       do {
 # define BUF_LEN    ((sizeof(struct inotify_event)+NAME_MAX+1))
+       while (!got_close) {
            unsigned char buf[BUF_LEN];
            ssize_t e;
 
@@ -133,14 +134,15 @@
                struct inotify_event *ev;
 
                ev = (struct inotify_event *)&buf[e];
-               if (ev->wd == wd && (ev->mask&IN_CLOSE))
+               if (ev->wd == wd && (ev->mask & IN_CLOSE)) {
+                   got_close = 1;
                    break;
+               }
 
                e += sizeof(struct inotify_event) + ev->len;
            }
-
 # undef BUF_LEN
-       } while (0);
+       }
 
        tcdrain(fd);
        close(fd);
@@ -148,6 +150,8 @@
 
     } while(0);
 out:
+    if (wd >= 0)
+       (void)inotify_rm_watch(nd, wd);
     close(nd);
     return fd;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.45/libconsole/vmcp.c 
new/showconsole-2.46/libconsole/vmcp.c
--- old/showconsole-2.45/libconsole/vmcp.c      2026-07-02 11:25:23.000000000 
+0200
+++ new/showconsole-2.46/libconsole/vmcp.c      2026-07-09 15:29:51.000000000 
+0200
@@ -113,6 +113,8 @@
 char* queryterm(int fd)
 {
     const char* question = "QUERY TERMINAL";
+    /* Reset cached terminal state before reparsing a fresh QUERY TERMINAL 
reply. */
+    clearvmcp();
     return askvmcp(fd, question);
 }
 

Reply via email to