This is an automated email from the git hooks/post-receive script.

guillem pushed a commit to branch main
in repository dpkg.

View the commit online:
https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=4d4e2e1186acae606de0b1f82ca888b6772ea89e

commit 4d4e2e1186acae606de0b1f82ca888b6772ea89e
Author: Guillem Jover <guil...@debian.org>
AuthorDate: Tue Feb 8 22:45:33 2022 +0100

    dselect: Rework windows resize to be signal safe
    
    Remove all current explicit signal handling code for window resizes
    and instead rely on ncurses doing this for us, which is going to be
    async-signal-safe, instead of the current code which was not.
    
    Changelog: internal
---
 dselect/basecmds.cc      |  2 +-
 dselect/baselist.cc      | 68 +++++-------------------------------------------
 dselect/dselect.h        |  8 ++----
 dselect/methlist.cc      | 15 +++++------
 dselect/pkglist.cc       | 15 +++++------
 t/cppcheck/cppcheck.supp |  3 ---
 6 files changed, 23 insertions(+), 88 deletions(-)

diff --git a/dselect/basecmds.cc b/dselect/basecmds.cc
index ef693d4c4..693784855 100644
--- a/dselect/basecmds.cc
+++ b/dselect/basecmds.cc
@@ -119,7 +119,7 @@ void baselist::kd_search() {
   echo();
   if (wgetnstr(querywin,newsearchstring,sizeof(newsearchstring)-1) == ERR)
     searchstring[0]= 0;
-  raise(SIGWINCH);
+  resize_window();
   noecho();
   if (whatinfo_height) { touchwin(whatinfowin); refreshinfo(); }
   else if (info_height) { touchwin(infopad); refreshinfo(); }
diff --git a/dselect/baselist.cc b/dselect/baselist.cc
index fd96db3e1..ec8cf4da8 100644
--- a/dselect/baselist.cc
+++ b/dselect/baselist.cc
@@ -48,70 +48,14 @@ void mywerase(WINDOW *win) {
   wmove(win,0,0);
 }
 
-baselist *baselist::signallist = nullptr;
-void baselist::sigwinchhandler(int) {
-  int save_errno = errno;
-  struct winsize size;
-  debug(dbg_general, "baselist::sigwinchhandler(), signallist=%p", signallist);
-  baselist *p= signallist;
-  p->enddisplay();
-  endwin(); initscr();
-  if (ioctl(fileno(stdout), TIOCGWINSZ, &size) != 0) 
ohshite(_("ioctl(TIOCGWINSZ) failed"));
-  resizeterm(size.ws_row, size.ws_col); wrefresh(curscr);
-  p->startdisplay();
-  if (doupdate() == ERR) ohshite(_("doupdate in SIGWINCH handler failed"));
-  errno = save_errno;
-}
-
-static void cu_sigwinch(int, void **argv) {
-  struct sigaction *osigactp = static_cast<struct sigaction *>(argv[0]);
-  sigset_t *oblockedp = static_cast<sigset_t *>(argv[1]);
-
-  if (sigaction(SIGWINCH, osigactp, nullptr))
-    ohshite(_("failed to restore old SIGWINCH sigact"));
-  delete osigactp;
-  if (sigprocmask(SIG_SETMASK, oblockedp, nullptr))
-    ohshite(_("failed to restore old signal mask"));
-  delete oblockedp;
-}
-
-void
-baselist::sigwinch_mask(int how)
-{
-  sigset_t sigwinchset;
-  sigemptyset(&sigwinchset);
-  sigaddset(&sigwinchset,SIGWINCH);
-
-  int rc = sigprocmask(how, &sigwinchset, nullptr);
-  if (rc < 0) {
-    if (how == SIG_UNBLOCK)
-      ohshite(_("failed to unblock SIGWINCH"));
-    else
-      ohshite(_("failed to block SIGWINCH"));
-  }
-}
-
 void
-baselist::setupsigwinch()
+baselist::resize_window()
 {
-  struct sigaction *osigactp = new(struct sigaction);
-  sigset_t *oblockedp = new(sigset_t);
-  if (sigprocmask(0, nullptr, oblockedp))
-    ohshite(_("failed to get old signal mask"));
-  if (sigaction(SIGWINCH, nullptr, osigactp))
-    ohshite(_("failed to get old SIGWINCH sigact"));
-
-  push_cleanup(cu_sigwinch, ~0, 2, osigactp, oblockedp);
-
-  sigwinch_mask(SIG_BLOCK);
-
-  struct sigaction nsigact;
-  memset(&nsigact,0,sizeof(nsigact));
-  nsigact.sa_handler= sigwinchhandler;
-  sigemptyset(&nsigact.sa_mask);
-//nsigact.sa_flags= SA_INTERRUPT;
-  if (sigaction(SIGWINCH, &nsigact, nullptr))
-    ohshite(_("failed to set new SIGWINCH sigact"));
+  debug(dbg_general, "baselist::resize_window(), baselist=%p", this);
+  enddisplay();
+  startdisplay();
+  if (doupdate() == ERR)
+    ohshite(_("cannot update screen after window resize"));
 }
 
 void
diff --git a/dselect/dselect.h b/dselect/dselect.h
index e620f5af8..e3ec37603 100644
--- a/dselect/dselect.h
+++ b/dselect/dselect.h
@@ -97,12 +97,8 @@ protected:
   // If listpad is null, then we have not started to display yet, and
   // so none of the auto-displaying update routines need to display.
 
-  // SIGWINCH handling
-  void sigwinch_mask(int how);
-  void setupsigwinch();
-
-  static baselist *signallist;
-  static void sigwinchhandler(int);
+  // Window resize handling (via SIGWINCH).
+  void resize_window();
 
   int nitems, ldrawnstart, ldrawnend, showinfo;
   int topofscreen, leftofscreen, cursorline;
diff --git a/dselect/methlist.cc b/dselect/methlist.cc
index 6cc280cf4..54382c546 100644
--- a/dselect/methlist.cc
+++ b/dselect/methlist.cc
@@ -157,19 +157,19 @@ quitaction methodlist::display() {
 
   debug(dbg_general, "methodlist[%p]::display()", this);
 
-  setupsigwinch();
   startdisplay();
 
   debug(dbg_general, "methodlist[%p]::display() entering loop", this);
   for (;;) {
     if (whatinfo_height) wcursyncup(whatinfowin);
     if (doupdate() == ERR) ohshite(_("doupdate failed"));
-    signallist= this;
-    sigwinch_mask(SIG_UNBLOCK);
-    do
-    response= getch();
-    while (response == ERR && errno == EINTR);
-    sigwinch_mask(SIG_BLOCK);
+    do {
+      response = getch();
+      if (response == KEY_RESIZE) {
+        resize_window();
+        continue;
+      }
+    } while (response == ERR && errno == EINTR);
     if (response == ERR) ohshite(_("getch failed"));
     interp= (*bindings)(response);
     debug(dbg_general, "methodlist[%p]::display() response=%d interp=%s",
@@ -178,7 +178,6 @@ quitaction methodlist::display() {
     (this->*(interp->mfn))();
     if (interp->qa != qa_noquit) break;
   }
-  pop_cleanup(ehflag_normaltidy); // unset the SIGWINCH handler
   enddisplay();
 
   debug(dbg_general, "methodlist[%p]::display() done", this);
diff --git a/dselect/pkglist.cc b/dselect/pkglist.cc
index 9ffe85517..54df0fc40 100644
--- a/dselect/pkglist.cc
+++ b/dselect/pkglist.cc
@@ -585,7 +585,6 @@ pkginfo **packagelist::display() {
 
   debug(dbg_general, "packagelist[%p]::display()", this);
 
-  setupsigwinch();
   startdisplay();
 
   if (!expertmode)
@@ -596,12 +595,13 @@ pkginfo **packagelist::display() {
     if (whatinfo_height) wcursyncup(whatinfowin);
     if (doupdate() == ERR)
       ohshite(_("doupdate failed"));
-    signallist= this;
-    sigwinch_mask(SIG_UNBLOCK);
-    do
-    response= getch();
-    while (response == ERR && errno == EINTR);
-    sigwinch_mask(SIG_BLOCK);
+    do {
+      response = getch();
+      if (response == KEY_RESIZE) {
+        resize_window();
+        continue;
+      }
+    } while (response == ERR && errno == EINTR);
     if (response == ERR)
       ohshite(_("getch failed"));
     interp= (*bindings)(response);
@@ -611,7 +611,6 @@ pkginfo **packagelist::display() {
     (this->*(interp->pfn))();
     if (interp->qa != qa_noquit) break;
   }
-  pop_cleanup(ehflag_normaltidy); // unset the SIGWINCH handler
   enddisplay();
 
   if (interp->qa == qa_quitnochecksave ||
diff --git a/t/cppcheck/cppcheck.supp b/t/cppcheck/cppcheck.supp
index 4d2741fc2..6a64e1be7 100644
--- a/t/cppcheck/cppcheck.supp
+++ b/t/cppcheck/cppcheck.supp
@@ -62,6 +62,3 @@ va_end_missing:lib/dpkg/parsehelp.c:68
 
 // BUG: False positive, due to our local va_copy().
 va_list_usedBeforeStarted:lib/compat/vasprintf.c
-
-// BUG: False positive, SIGWINCH is not a fatal signal.
-unreachableCode:dselect/basecmds.cc:123

-- 
Dpkg.Org's dpkg

Reply via email to