Here's another whopper, the old "dselect crashes when I resize xterm" bug. I basically snatched a few lines from view.c (an ncurses example file found in /usr/doc/libncurses4-dev/examples) to handle SIGWINCH, so this is pretty much a textbook example. Thanks to Sean 'Shaleh' Perry <shaleh@debian.org> for the pointers on what to look for. This patch also has the odd affect of allowing dselect to actually resize its display with the window. If the window is too small, ncurses causes a beep, and doesn't display. Ben
diff -urN dpkg-1.4.1.13.old/dselect/dselect.h dpkg-1.4.1.13/dselect/dselect.h --- dpkg-1.4.1.13.old/dselect/dselect.h Sun Nov 1 11:04:31 1998 +++ dpkg-1.4.1.13/dselect/dselect.h Mon Oct 11 13:20:51 1999 @@ -27,6 +27,17 @@ #include <signal.h> +#if defined(SIGWINCH) && defined(TIOCGWINSZ) && defined(NCURSES_VERSION) +#define CAN_RESIZE 1 +#else +#define CAN_RESIZE 0 +#endif + +#if CAN_RESIZE +static RETSIGTYPE adjust(int sig); +static int interrupted; +#endif + struct helpmenuentry { char key; const struct helpmessage *msg; diff -urN dpkg-1.4.1.13.old/dselect/main.cc dpkg-1.4.1.13/dselect/main.cc --- dpkg-1.4.1.13.old/dselect/main.cc Sun Nov 1 11:04:37 1998 +++ dpkg-1.4.1.13/dselect/main.cc Mon Oct 11 13:20:37 1999 @@ -96,6 +96,32 @@ stdout)) werr("stdout"); } +#if CAN_RESIZE +/* + * This uses functions that are "unsafe", but it seems to work on SunOS and + * Linux. The 'wrefresh(curscr)' is needed to force the refresh to start from + * the top of the screen -- some xterms mangle the bitmap while resizing. + * + * Borrowed from the ncurses example view.c + */ +static RETSIGTYPE adjust(int sig) +{ + if (waiting || sig == 0) { + struct winsize size; + + if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) { + resizeterm(size.ws_row, size.ws_col); + wrefresh(curscr); /* Linux needs this */ + show_all(); + } + interrupted = FALSE; + } else { + interrupted = TRUE; + } + (void) signal(SIGWINCH, adjust); /* some systems need this */ +} +#endif /* CAN_RESIZE */ + /* These are called by C code, so need to have C calling convention */ extern "C" { @@ -279,6 +305,10 @@ int main(int, const char *const *argv) { jmp_buf ejbuf; + +#if CAN_RESIZE + (void) signal(SIGWINCH, adjust); /* arrange interrupts to resize */ +#endif if (setjmp(ejbuf)) { /* expect warning about possible clobbering of argv */ cursesoff(); diff -urN dpkg-1.4.1.13.old/dselect/pkglist.cc dpkg-1.4.1.13/dselect/pkglist.cc --- dpkg-1.4.1.13.old/dselect/pkglist.cc Sun Nov 1 11:04:54 1998 +++ dpkg-1.4.1.13/dselect/pkglist.cc Mon Oct 11 13:17:18 1999 @@ -490,16 +490,22 @@ setupsigwinch(); startdisplay(); displayhelp(helpmenulist(),'i'); if (debug) fprintf(debug,"packagelist[%p]::display() entering loop\n",this); for (;;) { +#if CAN_RESIZE + if (interrupted) + adjust(0); +#endif if (whatinfo_height) wcursyncup(whatinfowin); if (doupdate() == ERR) ohshite("doupdate failed"); signallist= this; if (sigprocmask(SIG_UNBLOCK,&sigwinchset,0)) ohshite("failed to unblock SIGWINCH"); response= getch(); if (sigprocmask(SIG_BLOCK,&sigwinchset,0)) ohshite("failed to re-block SIGWINCH"); +#if CAN_RESIZE if (response == ERR) ohshite("getch failed"); +#endif interp= (*bindings)(response); if (debug) fprintf(debug,"packagelist[%p]::display() response=%d interp=%s\n",
Attachment:
pgpeD_UNbTnQz.pgp
Description: PGP signature