[Pinfo-devel] [PATCH] handle terminal stop/continue properly
Scott Mcdermott
scott at omnisys.com
Wed Sep 8 22:36:46 UTC 2010
Hello,
Pinfo has a bug where it can't be used after being
continued from job stop in the shell (i.e. control-z).
It will eat a CPU after resume, endlessly doing main
keypress handling loop because every time it calls
curses getch() after suspend, it will get ERR, until
curses has been "reset." The terminal needs to be
handed back to the calling program (i.e. bash) for
suspend, and then refreshed on resume.
I am surprised this bug went so long unfixed, because
using multiple jobs in a shell seems like a common
activity.
I debugged this and made the following patch, which
works well for me.
Please apply. Thanks.
Index: src/utils.c
===================================================================
--- src/utils.c (revision 308)
+++ src/utils.c (working copy)
@@ -376,10 +376,15 @@
void
waitforgetch()
{
+ int ret;
+
fd_set rdfs;
FD_ZERO(&rdfs);
FD_SET(0, &rdfs);
- select(1, &rdfs, NULL, NULL, NULL);
+
+ /* we might get interrupted by e.g. SIGTSTP/SIGCONT */
+ do ret = select(1, &rdfs, NULL, NULL, NULL);
+ while (ret == -1 && errno == EINTR);
}
/* returns 0 on success, 1 on error */
Index: src/signal_handler.c
===================================================================
--- src/signal_handler.c (revision 308)
+++ src/signal_handler.c (working copy)
@@ -44,6 +44,29 @@
}
void
+handle_suspend(int signum)
+{
+ if (!isendwin()) {
+ curs_set(1);
+ endwin();
+ }
+ fprintf(stderr, "\n");
+ signal(SIGTSTP, handle_suspend);
+ kill(0, SIGSTOP);
+}
+
+void
+handle_resume(int signum)
+{
+ if (isendwin()) {
+ refresh();
+ curs_set(0);
+ }
+ ungetch(keys.refresh_1);
+ signal(SIGCONT, handle_resume);
+}
+
+void
signal_handler()
{
sigset_t sigs;
@@ -52,6 +75,8 @@
signal(SIGTERM, handle_crash); /* handle soft kill */
signal(SIGSEGV, handle_crash); /* handle seg. fault */
signal(SIGHUP, handle_crash); /* handle hup signal */
+ signal(SIGTSTP, handle_suspend);/* handle terminal suspend */
+ signal(SIGCONT, handle_resume); /* handle back from suspend */
#ifdef SIGWINCH
signal(SIGWINCH, handle_window_resize);
#endif
Index: src/manual.c
===================================================================
--- src/manual.c (revision 308)
+++ src/manual.c (working copy)
@@ -967,7 +967,7 @@
key = pinfo_getch();
}
/************************ keyboard handling **********************************/
- if (key != 0)
+ if (key > 0)
{
if ((key == keys.print_1) ||
(key == keys.print_2))
More information about the Pinfo-devel
mailing list