Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package blog for openSUSE:Factory checked in 
at 2025-04-29 16:39:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/blog (Old)
 and      /work/SRC/openSUSE:Factory/.blog.new.30101 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "blog"

Tue Apr 29 16:39:44 2025 rev:21 rq:1273161 version:2.35

Changes:
--------
--- /work/SRC/openSUSE:Factory/blog/blog.changes        2025-04-20 
19:50:21.696861330 +0200
+++ /work/SRC/openSUSE:Factory/.blog.new.30101/blog.changes     2025-04-29 
16:39:48.280739083 +0200
@@ -1,0 +2,13 @@
+Mon Apr 28 13:42:43 UTC 2025 - Dr. Werner Fink <wer...@suse.de>
+
+- Update to version 2.35
+  * Make s390 3215 console work that is use EPOLLOUT|EPOLLONESHOT
+    to control if we can write to ttyS0 in nonblocking mode and if
+    not reenable EPOLLOUT|EPOLLONESHOT.
+  * At boot set for ttyS0 via vmcp API nonblocking MORE mode with
+    `0 0'.  It beeps but boots.
+- Remove patches now upstream
+  * blog-3215.patch
+  * blog-install.patch 
+
+-------------------------------------------------------------------

Old:
----
  blog-3215.patch
  blog-install.patch
  showconsole-2.34.tar.gz

New:
----
  showconsole-2.35.tar.gz

BETA DEBUG BEGIN:
  Old:- Remove patches now upstream
  * blog-3215.patch
  * blog-install.patch 
  Old:  * blog-3215.patch
  * blog-install.patch 
BETA DEBUG END:

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

Other differences:
------------------
++++++ blog.spec ++++++
--- /var/tmp/diff_new_pack.6SEkPR/_old  2025-04-29 16:39:49.048771342 +0200
+++ /var/tmp/diff_new_pack.6SEkPR/_new  2025-04-29 16:39:49.052771511 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           blog
-Version:        2.34
+Version:        2.35
 %define sonum   2
 Release:        0
 Summary:        Boot logging
@@ -26,8 +26,6 @@
 URL:            https://github.com/bitstreamout/showconsole
 Source:         
https://github.com/bitstreamout/showconsole/archive/v%{version}.tar.gz#/showconsole-%{version}.tar.gz
 Source1:        blog-rpmlintrc
-Patch0:         blog-install.patch
-Patch1:         blog-3215.patch
 BuildRequires:  bash
 %if 0%{suse_version} >= 1550
 # regenerate_initrd_post moved to rpm-config-SUSE:initrd.macros
@@ -89,8 +87,6 @@
 
 %prep
 %setup -q -n showconsole-%version
-%patch -P0
-%patch -P1
 for l in rt util pthread
 do
     ln -sf %{_libdir}/lib${l}.so.[0-9] lib${l}.so

++++++ showconsole-2.34.tar.gz -> showconsole-2.35.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/Makefile 
new/showconsole-2.35/Makefile
--- old/showconsole-2.34/Makefile       2025-04-16 14:56:56.000000000 +0200
+++ new/showconsole-2.35/Makefile       2025-04-28 15:35:31.000000000 +0200
@@ -15,7 +15,7 @@
 DEBUG   =
 DESTDIR         =
 MAJOR   :=     2
-MINOR   :=     34
+MINOR   :=     35
 VERSION         :=     $(MAJOR).$(MINOR)
 DATE    =      $(shell date +'%d%b%y' | tr '[:lower:]' '[:upper:]')
 COPTS    =
@@ -83,7 +83,7 @@
        $(SED) '$(SEDOPTS)' $< > $@
 
 $(libfiles):  $(L)libconsole.h listing.h
-libconsole.a: $(patsubst %.c,%.o,$(libfiles))
+libconsole.a: $(patsubst %.c,%.o,$(libfiles)) $(L)libconsole.h listing.h
        $(AR) rusv $@ $^
 
 libblogger.o:  libconsole.a
@@ -137,50 +137,28 @@
        $(INSTSCR) module-setup.sh      $(DESTDIR)$(DRACUTMOD)/
        $(LINK) libblogger.so.$(MAJOR).$(MINOR) 
$(DESTDIR)$(LIBDIR)/libblogger.so.$(MAJOR)
        $(LINK) libblogger.so.$(MAJOR).$(MINOR) 
$(DESTDIR)$(LIBDIR)/libblogger.so
-       for unit in blog blog-final blog-quit blog-store-messages 
blog-switch-root blog-switch-initramfs blog-umount ; do \
-           $(INSTCON) $${unit}.service $(DESTDIR)$(SYSDUNITS)/ ; \
-       done
-       for unit in systemd-ask-password-blog.path 
systemd-ask-password-blog.service ; do \
-           $(INSTCON) $${unit}         $(DESTDIR)$(SYSDUNITS)/ ; \
-       done
-       for target in default sysinit basic local-fs-pre halt rescue shutdown 
reboot poweroff kexec emergency initrd-switch-root; do \
-           $(MKDIR) $(DESTDIR)$(SYSDUNITS)/$${target}.target.wants ; \
-       done
-       for service in systemd-ask-password-blog ; do \
-           $(MKDIR) $(DESTDIR)$(SYSDUNITS)/$${target}.service.wants ; \
-       done
-       for unit in blog-quit.service ; do \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/default.target.wants/$${unit} ; \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/rescue.target.wants/$${unit} ; \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/emergency.target.wants/$${unit} ; \
-       done
-       for unit in blog.service ; do \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/basic.target.wants/$${unit} ; \
-       done
-       for unit in blog-store-messages.service systemd-ask-password-blog.path 
; do \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/sysinit.target.wants/$${unit} ; \
-       done
-       for unit in blog-umount.service ; do \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/local-fs-pre.target.wants/$${unit} ; \
-       done
-       for unit in blog-switch-initramfs.service ; do \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/reboot.target.wants/$${unit} ; \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/poweroff.target.wants/$${unit} ; \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/kexec.target.wants/$${unit} ; \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/halt.target.wants/$${unit} ; \
-       done
-       for unit in reboot poweroff kexec halt ; do \
-           $(LINK) ../blog-$${unit}.service 
$(DESTDIR)$(SYSDUNITS)/$${unit}.target.wants/blog-$${unit}.service ; \
-       done
-       for target in systemd-ask-password-blog.service ; do \
-           $(MKDIR) $(DESTDIR)$(SYSDUNITS)/$${target}.wants ; \
-       done
-       for unit in blog.service blog-switch-root.service ; do \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/initrd-switch-root.target.wants/$${unit} ; \
-       done
-       for unit in systemd-vconsole-setup.service ; do \
-           $(LINK) ../$${unit} 
$(DESTDIR)$(SYSDUNITS)/systemd-ask-password-blog.service.wants/$${unit} ; \
-       done
+       @set +x; \
+       export initdir=$(DESTDIR); \
+       export systemdsystemunitdir=$(SYSDUNITS); \
+       inst_multiple () { \
+           if test $$1 = -o; then \
+                shift; \
+                for o; do \
+                    test -e $${o##*/} && command install -vp -m 0644 $${o##*/} 
$${initdir}$${o} || : ; \
+                done; \
+           else \
+               command install -vp -m 0755 $${1##*/} $${initdir}$(SBINDIR)/; \
+           fi; \
+       }; \
+       ln_r () { \
+           local rel="$$(realpath -m --relative-to=$${2%/*}/ $${1%/*}/)"; \
+           ln -sf $${rel}/$${1##*/} $${initdir}$${2}; }; \
+       . ./module-setup.sh ; \
+       set -xe; install
+       $(MKDIR)        $(DESTDIR)$(SYSDUNITS)/local-fs-pre.target.wants
+       $(MKDIR)        $(DESTDIR)$(SYSDUNITS)/default.target.wants
+       $(LINK) ../blog-umount.service  
$(DESTDIR)$(SYSDUNITS)/local-fs-pre.target.wants/
+       $(LINK) ../blog-quit.service    
$(DESTDIR)$(SYSDUNITS)/default.target.wants/
 
 #
 # Make distribution
@@ -205,8 +183,11 @@
          isserial.c    \
          isserial.8    \
          blog.service                          \
-         blog-final.service                    \
+         blog-halt.service                     \
+         blog-kexec.service                    \
+         blog-poweroff.service                 \
          blog-quit.service                     \
+         blog-reboot.service                   \
          blog-store-messages.service.in        \
          blog-switch-root.service              \
          blog-switch-initramfs.service         \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/blog-store-messages.service.in 
new/showconsole-2.35/blog-store-messages.service.in
--- old/showconsole-2.34/blog-store-messages.service.in 2025-04-16 
14:56:56.000000000 +0200
+++ new/showconsole-2.35/blog-store-messages.service.in 2025-04-28 
15:35:31.000000000 +0200
@@ -1,9 +1,13 @@
 [Unit]
 Description=Tell blogd about writable boot log
 DefaultDependencies=no
+RequiresMountsFor=/var/log/boot.log
+Conflicts=shutdown.target
+After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service
 After=local-fs.target
 Before=sysinit.target
 ConditionPathExists=!/etc/initrd-release
+ConditionPathIsReadWrite=/var/log
 
 [Service]
 Type=oneshot
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/blog.service 
new/showconsole-2.35/blog.service
--- old/showconsole-2.34/blog.service   2025-04-16 14:56:56.000000000 +0200
+++ new/showconsole-2.35/blog.service   2025-04-28 15:35:31.000000000 +0200
@@ -6,6 +6,7 @@
 Before=systemd-ask-password-blog.service
 ConditionKernelCommandLine=!blog.enable=0
 ConditionVirtualization=!container
+ConditionPathExists=/dev/console
 IgnoreOnIsolate=true
 RefuseManualStart=true
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/blogd.c new/showconsole-2.35/blogd.c
--- old/showconsole-2.34/blogd.c        2025-04-16 14:56:56.000000000 +0200
+++ new/showconsole-2.35/blogd.c        2025-04-28 15:35:31.000000000 +0200
@@ -191,9 +191,11 @@
 /*
  * To be able to reconnect to real tty on EIO
  */
-static void reconnect(int fd)
+static int reconnect(int fd)
 {
     struct console * c;
+    int ret = 0, tflags;
+    int olderr = errno;
 
     list_for_each_entry(c, &cons->node, node) {
        int newfd;
@@ -209,12 +211,27 @@
        default:        /* IO of system consoles */
            if ((newfd = open_tty(c->tty, 
O_WRONLY|O_NONBLOCK|O_NOCTTY|O_CLOEXEC)) < 0)
                error("can not open %s: %m", c->tty);
+           epoll_delete(c->fd);
            dup2(newfd, c->fd);
            if (newfd != c->fd)
                close(newfd);
+           epoll_addwrite(c->fd, &epoll_write_watchdog);
+            ret = 1;
+#if defined(__s390__) || defined(__s390x__)
+           if (major(c->dev) == 4 && minor(c->dev) == 64)
+               break;
+#endif
+           if ((tflags = fcntl(c->fd, F_GETFL)) < 0)
+               warn("can not get terminal flags of %s", c->tty);
+           tflags &= ~(O_NONBLOCK);
+           if (fcntl(c->fd, F_SETFL, tflags) < 0)
+               warn("can not set terminal flags of %s", c->tty);
            break;
        }
     }
+    errno = olderr;
+
+    return ret;
 }
 
 
@@ -222,6 +239,9 @@
 
 static void flush_handler (void) attribute((noinline));
 static void exit_handler (void) attribute((noinline));
+#if defined(__s390__) || defined(__s390x__)
+static void vmcp_handler (void) attribute((noinline));
+#endif
 
 /*
  * Now do the job
@@ -325,8 +345,22 @@
            o.c_cc[VMIN]  = CMIN;
        }
 #if defined(__s390__) || defined(__s390x__)
-       if (major(c->dev) == 4 && minor(c->dev) == 65) {
-           ioctl(c->fd, TIOCSBRK);
+       if (major(c->dev) == 4 && minor(c->dev) == 64 && final == 0) {
+           char *msg;
+           int vmcp;
+
+           vmcp = openvmcp();
+           if (vmcp) {
+               msg = queryterm(vmcp);
+               if (msg) {
+                   parseterm(msg);
+                   free(msg);
+                   setterm(vmcp);
+               }
+               close(vmcp);
+               atexit(vmcp_handler);   /* Register vmcp restore exit handler */
+           }
+           ioctl(c->fd, TIOCCBRK);
            usleep(1000);
        }
 #endif
@@ -605,3 +639,13 @@
     reset_signal(SIGTERM, &saved_sigterm);
     reset_signal(SIGSYS,  &saved_sigsys);
 }
+
+#if defined(__s390__) || defined(__s390x__)
+static void vmcp_handler (void)
+{
+    int vmcp = openvmcp();
+    if (vmcp >= 0)
+       restoreterm(vmcp);
+    close(vmcp);
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/libconsole/console.c 
new/showconsole-2.35/libconsole/console.c
--- old/showconsole-2.34/libconsole/console.c   2025-04-16 14:56:56.000000000 
+0200
+++ new/showconsole-2.35/libconsole/console.c   2025-04-28 15:35:31.000000000 
+0200
@@ -26,6 +26,7 @@
 #include <sys/klog.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
+#include <sys/select.h>                /* declares fd_set */
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -69,6 +70,13 @@
 volatile sig_atomic_t asking;
 
 /*
+ * One of the device for console are blocked if true.
+ */
+static fd_set blocked;
+static const fd_set empty;
+#define FD_BUSY(arg)   (memcmp(arg, &empty, sizeof(fd_set)) != 0)
+
+/*
  * Move log file to old file
  */
 int final = 0;
@@ -117,23 +125,29 @@
 }
 
 /*
+ * The stdio file pointer for our log file
+ */
+struct console *cons;
+static FILE * flog = NULL;
+static int fdread  = -1;
+static int fdfifo  = -1;
+
+static int fdsock  = -1;
+static char *pwprompt;
+static char *password;
+static int32_t *pwsize;
+
+/*
  * Arg used: safe out
  */
-static void (*vc_reconnect)(int fd);
+static int (*vc_reconnect)(int fd);
 void safeout (int fd, const void *ptr, size_t s, ssize_t max)
 {
     int saveerr = errno;
-    int issocket = 0;
-    struct stat st;
-
-    if (fstat(fd, &st) < 0)
-       goto out;
-    if (S_ISSOCK(st.st_mode))
-       issocket++;
 
     while (s > 0) {
        ssize_t p;
-       if (issocket) {
+       if (fdsock == fd) {             /* We use only ONE socket, no fstat() 
required */
            int flags = MSG_NOSIGNAL;
            if (s > max)
                flags |= MSG_MORE;
@@ -142,7 +156,7 @@
            p = write (fd, ptr, (max < 1) ? 1 : ((s < (size_t)max) ? s : 
(size_t)max));
        if (p < 0) {
            if (errno == EPIPE)
-               break;
+               break;                  /* Drop the rest of the message */
 
            if (errno == EINTR) {
                errno = 0;
@@ -150,15 +164,19 @@
            }
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
 
-               /* Avoid high load: wait upto two seconds if system is not 
ready */
-               if (can_write(fd, 2))
+               /* Avoid high load: wait upto 100 milli seconds if system is 
not ready */
+               if (can_write(fd, 100))
                    continue;
+
+               FD_SET(fd, &blocked);
+               epoll_reenable(fd);
+               break;                  /* Drop the rest of the message */
            }
            if (errno == EIO) {
                if (!vc_reconnect)
                    lerror("can not write to fd %d", fd);
-
-               (*vc_reconnect)(fd);
+               if (!(*vc_reconnect)(fd))
+                   lerror("can not write to fd %d", fd);
                errno = 0;
                continue;
            }
@@ -172,6 +190,51 @@
 }
 
 /*
+ * Arg used: copy out
+ */
+static ssize_t copyout (int fd, const void *ptr, size_t s, ssize_t max)
+{
+    int saveerr = errno;
+    ssize_t r = 0, p;
+    do {
+       p = write (fd, ptr, (max < 1) ? 1 : ((s < (size_t)max) ? s : 
(size_t)max));
+       if (p < 0) {
+           if (errno == EINTR) {
+               errno = 0;
+               continue;
+           }
+           if (errno == EAGAIN || errno == EWOULDBLOCK) {
+               FD_SET(fd, &blocked);
+               epoll_reenable(fd);
+               if (r == 0)
+                   r = -1;
+               break;
+           }
+           if (errno == EIO) {
+               if (!vc_reconnect) {
+                   warn("can not write to fd %d", fd);
+                   break;
+               }
+               if (!(*vc_reconnect)(fd)) {
+                   warn("can not write to fd %d", fd);
+                   break;
+               }
+               errno = 0;
+               continue;
+           }
+           warn("can not write to fd %d", fd);
+            break;
+       }
+       ptr += p;
+       s -= p;
+       r += p;
+    } while (s > 0);
+
+    errno = saveerr;
+    return r;
+}
+
+/*
  * Twice used: safe in
  */
 
@@ -241,19 +304,6 @@
 }
 
 /*
- * The stdio file pointer for our log file
- */
-struct console *cons;
-static FILE * flog = NULL;
-static int fdread  = -1;
-static int fdfifo  = -1;
-
-static int fdsock  = -1;
-static char *pwprompt;
-static char *password;
-static int32_t *pwsize;
-
-/*
  * Signal control for writing on log file
  */
 volatile sig_atomic_t nsigsys;
@@ -276,7 +326,11 @@
 /*
  * Our temporary buffer during asking a password/passphrase
  */
+#if defined(__s390__) || defined(__s390x__)
+static      char temp[8*TRANS_BUFFER_SIZE];
+#else
 static      char temp[4*TRANS_BUFFER_SIZE];
+#endif
 static const char *const tend = temp + sizeof(temp);
 static       char *     thead = temp;
 static       char *     ttail = temp;
@@ -289,9 +343,12 @@
 static void epoll_console_in(int) attribute((noinline));
 static void epoll_fifo_in(int) attribute((noinline));
 static void epoll_socket_accept(int) attribute((noinline));
+void epoll_write_watchdog(int) attribute((noinline));
 
-void prepareIO(void (*rfunc)(int), const int listen, const int input)
+void prepareIO(int (*rfunc)(int), const int listen, const int input)
 {
+    struct console *c;
+
     (void)sigfillset(&omask);
     (void)sigdelset(&omask, SIGQUIT);
     (void)sigdelset(&omask, SIGTERM);
@@ -299,7 +356,7 @@
     (void)sigdelset(&omask, SIGIO);
 
     vc_reconnect = rfunc;
-    fdsock  = listen;
+    fdsock  = listen;                  /* We use only ONE socket ... see also 
safeout() */
     fdread  = input;
 
     if (fifo_name && fdfifo < 0) {
@@ -326,6 +383,12 @@
     if (fdsock >= 0)
        epoll_addread(fdsock, &epoll_socket_accept);
 
+    list_for_each_entry(c, &cons->node, node) {
+       if (c->fd < 0)
+           continue;
+       epoll_addwrite(c->fd, &epoll_write_watchdog);
+    }
+
     (void)mlockall(MCL_FUTURE);
 }
 
@@ -352,26 +415,22 @@
     safein_noexit = noerr;  /* Do or do not not exit on unexpected errors */
 
     for (n = 0; n < nfds; n++) {
-       if (evlist[n].events & (EPOLLIN|EPOLLPRI)) {
-           void (*efunc)(int);
-           int fd;
-           efunc = epoll_handle(evlist[n].data.ptr, &fd);
-           if (!efunc)
-               continue;
+       void (*efunc)(int);
+       int fd;
+       efunc = epoll_handle(evlist[n].data.ptr, &fd);
+       if (!efunc)
+           continue;
+       ret = 1;
+       if (evlist[n].events & (EPOLLIN|EPOLLOUT)) {
            efunc(fd);
-           ret = 1;
+           continue;
        }
-    }
-
-    for (n = 0; n < nfds; n++) {
-       if (evlist[n].events & (EPOLLOUT)) {
-           void (*efunc)(int);
-           int fd;
-           efunc = epoll_handle(evlist[n].data.ptr, &fd);
-           if (!efunc)
-               continue;
-           efunc(fd);
+       if (evlist[n].events & (EPOLLRDHUP|EPOLLHUP)) {
+           warn("epoll returns RDHUP or HUP");
+           continue;
        }
+       if (evlist[n].events & EPOLLERR)
+           warn("epoll returns error");
     }
 
     safein_noexit = 0;
@@ -598,11 +657,17 @@
     memset(&newc->ltio, 0, sizeof(newc->ltio));
     memset(&newc->otio, 0, sizeof(newc->otio));
     memset(&newc->ctio, 0, sizeof(newc->ctio));
+
+#if defined(__s390__) || defined(__s390x__)
+    if (major(newc->dev) == 4 && minor(newc->dev) == 64)
+       return 1;
+#endif
     if ((tflags = fcntl(newc->fd, F_GETFL)) < 0)
        warn("can not get terminal flags of %s", newc->tty);
 
     tflags &= ~(O_NONBLOCK);
     tflags |=   O_NOCTTY;
+
     if (fcntl(newc->fd, F_SETFL, tflags) < 0)
        warn("can not set terminal flags of %s", newc->tty);
 
@@ -788,18 +853,36 @@
 
        parselog(trans, cnt);                           /* Parse and make copy 
of the input */
 
+       list_for_each_entry(c, &cons->node, node) {
+           int len;
+           char *mesg;
+           if (c->fd < 0)
+               continue;
+           if (FD_ISSET(c->fd, &blocked))
+               break;                                  /* Let's wait on epoll 
event */
+           if (can_write(c->fd, 50))
+               continue;
+           FD_SET(c->fd, &blocked);
+           epoll_reenable(c->fd);
+           len = asprintf(&mesg, "blogd: console device %s is blocked", 
c->tty);
+           if (len < 0)
+               error("can not allocate string");
+           copylog(mesg, len);
+           free(mesg);
+       }
+
        /*
         * During asking a password/passphrase we are temporary
         * buffer console output to release it if we've got an answer.
         */
-       if (asking) {
+       if (asking || FD_BUSY(&blocked)) {
            if (cnt <= (size_t)(tend - ttail)) {
                memcpy(ttail, trans, cnt);
                tavail = (ttail += cnt) - thead;
            }
 
-           goto flush;                                 /* Temporary silent as 
waiting on passphrase */
-
+           goto flush;                                 /* Temporary silent as 
waiting on
+                                                          passphrase or 
console device */
        } else while (tavail > 0) {                     /* Empty temporary 
buffer if any */
            size_t len = (size_t)tavail;
 
@@ -807,9 +890,13 @@
                len = TRANS_BUFFER_SIZE;
 
            list_for_each_entry(c, &cons->node, node) {
+               size_t ret;
                if (c->fd < 0)
                    continue;
-               safeout(c->fd, thead, len, c->max_canon);
+               ret = copyout(c->fd, thead, len, c->max_canon);
+               if (ret < 1)
+                   goto flush;
+               len = ret;                              /* First make write out 
all but Second? */
                (void)tcdrain(c->fd);                   /* Write copy of input 
to real tty */
            }
            thead += len;
@@ -828,9 +915,17 @@
        }
 
        list_for_each_entry(c, &cons->node, node) {
+           size_t ret;
            if (c->fd < 0)
                continue;
-           safeout(c->fd, trans, cnt, c->max_canon);
+           ret = copyout(c->fd, trans, cnt, c->max_canon);
+           if (ret < 1) {
+               if (cnt <= (size_t)(tend - ttail)) {
+                   memcpy(ttail, trans, cnt);
+                   tavail = (ttail += cnt) - thead;
+               }
+               break;
+            }
            (void)tcdrain(c->fd);                       /* Write copy of input 
to real tty */
        }
 flush:
@@ -1213,6 +1308,14 @@
 }
 
 /*
+ * The watch dog for all outgoing terminals
+ */
+void epoll_write_watchdog(int fd)
+{
+    FD_CLR(fd, &blocked);
+}
+
+/*
  * Do handle the connection in data
  */
 char* currenttty;
@@ -1243,7 +1346,7 @@
     wait = 200;
     while (wait > 0 && (len = klogctl(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0)) > 
0) {
        usleep(1000);
-        wait--;
+       wait--;
     }
     wait = 0;
 
@@ -1278,6 +1381,8 @@
                epoll_close_fd();
                close(epfd);
            }
+            FD_ZERO(&blocked);
+           vc_reconnect = NULL;
 
            dup2(1, 2);
            dup2(c->fd, 0);
@@ -1286,7 +1391,6 @@
 
            list_for_each_entry(d, &cons->node, node)
                if (d->fd >= 0) {
-                   (void)tcdrain(d->fd);
                    close(d->fd);
                    d->fd = -1;
                }
@@ -1296,6 +1400,7 @@
            set_signal(SIGHUP,  NULL, SIG_DFL);
 
            prctl(PR_SET_PDEATHSIG, SIGHUP);
+           prctl(PR_SET_NAME, "login");
 
            set_signal(SIGCHLD, NULL, SIG_DFL);
            set_signal(SIGINT,  NULL, SIG_DFL);
@@ -1319,7 +1424,7 @@
                (major(c->dev) == 227 && minor(c->dev) >= 1))
                len = asprintf(&message, BOLD RED "\n\r%s: " NORM, pwprompt);
            else
-               len = asprintf(&message, "\n\r>> %s: ", pwprompt);
+               len = asprintf(&message, "\n\r===>> %s: ", pwprompt);
 #else
            if (c->flags & CON_SERIAL)
                len = asprintf(&message, BOLD RED "\n\r%s: " NORM, pwprompt);
@@ -1349,8 +1454,8 @@
            tcsetattr(0, TCSANOW, &c->ctio);
            safeout(1, "\n", 1, c->max_canon);
 
-            if (*pwsize == 0)
-                goto again;
+           if (*pwsize == 0)
+               goto again;
 
            if (*pwsize < 0)
                warn("can not read password");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/libconsole/epoll.c 
new/showconsole-2.35/libconsole/epoll.c
--- old/showconsole-2.34/libconsole/epoll.c     2025-04-16 14:56:56.000000000 
+0200
+++ new/showconsole-2.35/libconsole/epoll.c     2025-04-28 15:35:31.000000000 
+0200
@@ -28,14 +28,14 @@
     int fd;
 } *epolls;
 
-void epoll_addread(int fd, void *fptr)
+static inline void epoll_addition(int fd, void *fptr, uint32_t flags)
 {
     struct epoll_event ev = {};
     struct epolls *ep;
     list_t *head;
     int ret;
 
-    ev.events = EPOLLIN|EPOLLPRI;
+    ev.events = flags;
 
     if (posix_memalign((void**)&ep, sizeof(void*), alignof(struct epolls)) != 
0 || !ep)
        error("memory allocation");
@@ -58,6 +58,16 @@
        error("can not add %d file descriptor on epoll file descriptor", fd);
 }
 
+void epoll_addread(int fd, void *fptr)
+{
+    epoll_addition(fd, fptr, EPOLLIN|EPOLLPRI|EPOLLRDHUP);
+}
+
+void epoll_addwrite(int fd, void *fptr)
+{
+    epoll_addition(fd, fptr, EPOLLOUT|EPOLLONESHOT|EPOLLPRI|EPOLLERR);
+}
+
 void epoll_answer_once(int fd, void *fptr)
 {
     struct epoll_event ev = {};
@@ -88,6 +98,26 @@
        error("can not add %d file descriptor on epoll file descriptor", fd);
 }
 
+void epoll_reenable(int fd)
+{
+    struct epoll_event ev = {};
+    struct epolls *ep;
+
+    ev.events = EPOLLOUT|EPOLLONESHOT;
+
+    list_for_each_entry(ep, &lpolls, watch) {
+       if (ep->fd == fd) {
+           int ret;
+           ev.data.ptr = (void*)ep;
+           ret = epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);
+           if (ret < 0)
+               error("can not add %d file descriptor on epoll file 
descriptor", fd);
+           break;
+       }
+    }
+
+}
+
 void epoll_delete(int fd)
 {
     struct epolls *ep, *n;
@@ -95,8 +125,6 @@
 
     list_for_each_entry_safe(ep, n, &lpolls, watch) {
        if (ep->fd == fd) {
-           if (isatty(fd))
-               tcdrain(fd);
            delete(&ep->watch);
            free(ep);
            break;
@@ -118,8 +146,6 @@
        if (ep == ptr) {
            handle = ep->handle;
            *fd = ep->fd;
-           if (isatty(ep->fd))
-               tcdrain(ep->fd);
            break;
        }
     }
@@ -132,9 +158,6 @@
 {
     struct epolls *ep;
 
-    list_for_each_entry(ep, &lpolls, watch) {
-       if (isatty(ep->fd))
-           tcdrain(ep->fd);
+    list_for_each_entry(ep, &lpolls, watch)
        close(ep->fd);
-    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/libconsole/io.c 
new/showconsole-2.35/libconsole/io.c
--- old/showconsole-2.34/libconsole/io.c        2025-04-16 14:56:56.000000000 
+0200
+++ new/showconsole-2.35/libconsole/io.c        2025-04-28 15:35:31.000000000 
+0200
@@ -21,7 +21,7 @@
  * The sigset_t omask is given in console.c
  *
  */
-int can_read(int fd, const long timeout)
+int can_read(int fd, const time_t msec)
 {
     struct pollfd fds = {
        .fd = fd,
@@ -29,19 +29,19 @@
        .revents = 0,
     };
     struct timespec ts = {
-       .tv_sec = (time_t)(timeout/1000),
-       .tv_nsec = (timeout % 1000) * 1000000,
+       .tv_sec = (time_t)(msec/1000),
+       .tv_nsec = (msec % 1000) * 1000000,
     };
     int ret;
 
     do {
-       ret = ppoll(&fds, 1, (timeout < 0) ? NULL : &ts, &omask);
+       ret = ppoll(&fds, 1, (msec < 0) ? NULL : &ts, &omask);
     } while ((ret < 0) && (errno == EINTR));
 
     return (ret == 1) && (fds.revents & (POLLIN|POLLPRI));
 }
 
-int can_write(int fd, const int timeout)
+int can_write(int fd, const time_t msec)
 {
     struct pollfd fds = {
        .fd = fd,
@@ -49,13 +49,13 @@
        .revents = 0,
     };
     struct timespec ts = {
-       .tv_sec = (time_t)(timeout/1000),
-       .tv_nsec = (timeout % 1000) * 1000000,
+       .tv_sec = (time_t)(msec/1000),
+       .tv_nsec = (msec % 1000) * 1000000,
     };
     int ret;
 
     do {
-       ret = ppoll(&fds, 1, (timeout < 0) ? NULL : &ts, &omask);
+       ret = ppoll(&fds, 1, (msec < 0) ? NULL : &ts, &omask);
     } while ((ret < 0) && (errno == EINTR));
 
     return (ret == 1) && (fds.revents & (POLLOUT|POLLWRBAND));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/libconsole/libconsole.h 
new/showconsole-2.35/libconsole/libconsole.h
--- old/showconsole-2.34/libconsole/libconsole.h        2025-04-16 
14:56:56.000000000 +0200
+++ new/showconsole-2.35/libconsole/libconsole.h        2025-04-28 
15:35:31.000000000 +0200
@@ -127,12 +127,13 @@
 extern ssize_t safein (int fd, void *ptr, size_t s);
 extern void safeout (int fd, const void *ptr, size_t s, ssize_t max);
 
-extern void prepareIO(void (*rfunc)(int), const int listen, const int in);
+extern void prepareIO(int (*rfunc)(int), const int listen, const int in);
 extern void safeIO (void);
 extern void closeIO(void);
 
 extern struct console *cons;
 extern void getconsoles(struct console **cons, int io);
+extern void epoll_write_watchdog(int) attribute((noinline));
 
 /* chroot.c */
 extern void new_root(const char *root);
@@ -147,7 +148,9 @@
 
 /* epoll.c */
 extern void epoll_addread(int fd, void *fptr);
+extern void epoll_addwrite(int fd, void *fptr);
 extern void epoll_answer_once(int fd, void *fptr);
+extern void epoll_reenable(int fd);
 extern void epoll_delete(int fd);
 extern void (*epoll_handle(void *ptr, int *fd))(int);
 extern void epoll_close_fd(void);
@@ -156,8 +159,8 @@
 extern void *frobnicate(void *in, const size_t len);
 
 /* io.c */
-extern int can_read(int fd, const long timeout);
-extern int can_write(int fd, const int timeout);
+extern int can_read(int fd, const time_t msec);
+extern int can_write(int fd, const time_t msec);
 extern void clear_input(int fd);
 
 /* log.c */
@@ -198,6 +201,15 @@
 extern int open_tty(const char *name, int mode);
 extern int request_tty(const char *tty);
 
+/* vmcp.c */
+#if defined(__s390__) || defined(__s390x__)
+int openvmcp(void);
+char* queryterm(int fd);
+int setterm(int fd);
+int restoreterm(int fd);
+void parseterm(char *msg);
+#endif
+
 #define MAX_PASSLEN    LINE_MAX
 /* Some shorthands for control characters. */
 #define CTL(x)         ((x) ^ 0100)    /* Assumes ASCII dialect */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/libconsole/tty.c 
new/showconsole-2.35/libconsole/tty.c
--- old/showconsole-2.34/libconsole/tty.c       2025-04-16 14:56:56.000000000 
+0200
+++ new/showconsole-2.35/libconsole/tty.c       2025-04-28 15:35:31.000000000 
+0200
@@ -15,6 +15,7 @@
 #include <signal.h>
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
+#include <sys/sysmacros.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -52,6 +53,9 @@
 {
     struct sigaction saved_sighup;
     int fd = -1, nd, wd;
+#if defined(__s390__) || defined(__s390x__)
+    struct stat sb;
+#endif
 
     fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
     if (fd >= 0) {
@@ -95,9 +99,16 @@
            break;
        }
 
+#if defined(__s390__) || defined(__s390x__)
+       if (fstat(fd, &sb) == 0 && major(sb.st_dev) == 4 && minor(sb.st_dev) == 
64)
+           goto noblock;
+#endif
        flags = fcntl(fd, F_GETFL);
        flags &= ~O_NONBLOCK;
        fcntl(fd, F_SETFL, flags);
+#if defined(__s390__) || defined(__s390x__)
+    noblock:
+#endif
 
        if (ret >= 0)
            break;      /* Success */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/libconsole/vmcp.c 
new/showconsole-2.35/libconsole/vmcp.c
--- old/showconsole-2.34/libconsole/vmcp.c      1970-01-01 01:00:00.000000000 
+0100
+++ new/showconsole-2.35/libconsole/vmcp.c      2025-04-28 15:35:31.000000000 
+0200
@@ -0,0 +1,154 @@
+/*
+ * vmcp.c
+ *
+ * Based on:
+ *
+ * Copyright IBM Corp. 2018
+ * s390-tools is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ *
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include "libconsole.h"
+
+#if defined(__s390__) || defined(__s390x__)
+
+#define        VMCP_DEVICE_NODE        "/dev/vmcp"
+#define        VMCP_GETSIZE            _IOR(0x10, 3, int)
+#define        VMCP_SETBUF             _IOW(0x10, 2, int)
+#define        VMCP_GETCODE            _IOR(0x10, 1, int)
+
+int openvmcp(void)
+{
+    return open(VMCP_DEVICE_NODE, O_RDWR|O_NOCTTY);
+}
+
+char* queryterm(int fd)
+{
+    const char* question = "QUERY TERMINAL";
+    long pagesize = sysconf(_SC_PAGESIZE);
+    int rc = 0, num, buffersize;
+    char* ret = NULL;
+
+    num = (strlen(question) + pagesize - 1)/pagesize;
+    buffersize = num * pagesize;
+
+    if (ioctl(fd, VMCP_SETBUF, &buffersize) == -1)
+        goto out;
+    do {
+       rc = write(fd, question, strlen(question));
+        if (rc < 0) {
+           if (errno != EINTR)
+               goto out;
+        }
+    } while (rc < 0);
+    if (ioctl(fd, VMCP_GETCODE, &rc) == -1)
+        goto out;
+    if (ioctl(fd, VMCP_GETSIZE, &buffersize) == -1)
+        goto out;
+    ret = (char*)malloc(buffersize);
+    if (!ret)
+        goto out;
+    do {
+       rc = read(fd, ret, buffersize);
+        if (rc < 0) {
+           if (errno != EINTR)
+               goto out;
+        }
+    } while (rc < 0);
+out:
+    return ret;
+}
+
+int setterm(int fd)
+{
+    const char* instruction = "TERMINAL MORE 0 0 HOLD OFF";
+    long pagesize = sysconf(_SC_PAGESIZE);
+    int rc = 0, num, buffersize;
+    int ret = -1;
+
+    num = (strlen(instruction) + pagesize - 1)/pagesize;
+    buffersize = num * pagesize;
+
+    if (ioctl(fd, VMCP_SETBUF, &buffersize) == -1)
+        goto out;
+    do {
+       rc = write(fd, instruction, strlen(instruction));
+        if (rc < 0) {
+           if (errno != EINTR)
+               goto out;
+        }
+    } while (rc < 0);
+    if (ioctl(fd, VMCP_GETCODE, &rc) == -1)
+        goto out;
+    if (ioctl(fd, VMCP_GETSIZE, &buffersize) == -1)
+        goto out;
+    if (rc == 0 && buffersize == 0)
+       ret = 0;
+out:
+    return ret;
+}
+
+static char *more, *hold;
+
+int restoreterm(int fd)
+{
+    char* instruction;
+    long pagesize = sysconf(_SC_PAGESIZE);
+    int rc = 0, num, buffersize;
+    int ret = -1;
+
+    if (!more || !hold)
+       goto out;
+    if (asprintf(&instruction, "TERMINAL %s %s", more, hold) == -1)
+       goto out;
+
+    num = (strlen(instruction) + pagesize - 1)/pagesize;
+    buffersize = num * pagesize;
+
+    if (ioctl(fd, VMCP_SETBUF, &buffersize) == -1)
+        goto out;
+    do {
+       rc = write(fd, instruction, strlen(instruction));
+        if (rc < 0) {
+           if (errno != EINTR)
+               goto out;
+        }
+    } while (rc < 0);
+    free(instruction);
+    if (ioctl(fd, VMCP_GETCODE, &rc) == -1)
+        goto out;
+    if (ioctl(fd, VMCP_GETSIZE, &buffersize) == -1)
+        goto out;
+    if (rc == 0 && buffersize == 0)
+       ret = 0;
+out:
+    return ret;
+}
+
+void parseterm(char *msg)
+{
+    int n;
+    char *token, *ptr;
+    for (n = 1, ptr = msg; ; n++, ptr = NULL) {
+       token = strtok(ptr, ",\n");
+       if (!token)
+           break;
+       if (hold && more)
+           break;
+       while (*token == ' ')
+           token++;
+       if (strncmp("MORE ", token, 5) == 0)
+           more = strdup(token);
+       if (strncmp("HOLD ", token, 5) == 0)
+           hold = strdup(token);
+    }
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/module-setup.sh 
new/showconsole-2.35/module-setup.sh
--- old/showconsole-2.34/module-setup.sh        2025-04-16 14:56:56.000000000 
+0200
+++ new/showconsole-2.35/module-setup.sh        2025-04-28 15:35:31.000000000 
+0200
@@ -34,14 +34,14 @@
        ln_r "${systemdsystemunitdir}/${s}" 
"${systemdsystemunitdir}/rescue.target.wants/${s}"
        ln_r "${systemdsystemunitdir}/${s}" 
"${systemdsystemunitdir}/emergency.target.wants/${s}"
     done
-    for s in blog.service systemd-ask-password-blog.path
+    for s in blog.service blog-store-messages.service
     do
        ln_r "${systemdsystemunitdir}/${s}" 
"${systemdsystemunitdir}/sysinit.target.wants/${s}"
     done
     for u in reboot poweroff kexec halt
     do
        ln_r "${systemdsystemunitdir}/blog-${u}.service" 
"${systemdsystemunitdir}/${u}.target.wants/blog-${u}.service"
-       ln_r "${systemdsystemunitdir}/blog-switch-initramfs.service" 
"${systemdsystemunitdir}/${u}.target.wants/blog-switch-initramfs"
+       ln_r "${systemdsystemunitdir}/blog-switch-initramfs.service" 
"${systemdsystemunitdir}/${u}.target.wants/blog-switch-initramfs.service"
     done
     for t in systemd-ask-password-blog.service
     do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/systemd-ask-password-blog.path 
new/showconsole-2.35/systemd-ask-password-blog.path
--- old/showconsole-2.34/systemd-ask-password-blog.path 2025-04-16 
14:56:56.000000000 +0200
+++ new/showconsole-2.35/systemd-ask-password-blog.path 2025-04-28 
15:35:31.000000000 +0200
@@ -2,9 +2,12 @@
 Description=Forward Password Requests to Plymouth Directory Watch
 Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
 DefaultDependencies=no
-Conflicts=shutdown.target
 After=blog.service
-Before=basic.target shutdown.target
+Before=paths.target cryptsetup.target
+Conflicts=emergency.service
+Before=emergency.service
+Conflicts=shutdown.target
+Before=shutdown.target
 ConditionKernelCommandLine=!blog.enable=0
 ConditionPathExists=/run/blogd.pid
 ConditionVirtualization=!container
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/showconsole-2.34/systemd-ask-password-blog.service 
new/showconsole-2.35/systemd-ask-password-blog.service
--- old/showconsole-2.34/systemd-ask-password-blog.service      2025-04-16 
14:56:56.000000000 +0200
+++ new/showconsole-2.35/systemd-ask-password-blog.service      2025-04-28 
15:35:31.000000000 +0200
@@ -2,12 +2,15 @@
 Description=Forward Password Requests to Blogd as a Plymouth agent
 Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
 DefaultDependencies=no
-Conflicts=shutdown.target
-After=blog.service
-Before=shutdown.target
+After=blog.service systemd-vconsole-setup.service
+Conflicts=emergency.service
+Before=emergency.service
+Conflicts=shutdown.target initrd-switch-root.target
+Before=shutdown.target initrd-switch-root.target
 ConditionKernelCommandLine=!blog.enable=0
 ConditionVirtualization=!container
 ConditionPathExists=/run/blogd.pid
 
 [Service]
 ExecStart=/usr/bin/systemd-tty-ask-password-agent --watch --plymouth
+SystemCallArchitectures=native

Reply via email to