Currently if zombie keys are defined, one needs to explicitly hit a key to tell screen to try to reconnect a window. This is rather unfortunte if you for example have dozens of screens connected to foreign machines through network connections. Once the network connection is cut for a while, all windows will enter the dead/zombie state and one has to go through all windows manually and hit the zombie resurrect key, once the network got set up again.
This patch implements auto-reconnecting via zombie_timeout (in seconds) variable. By default it is set to 0 which complies to current behavior (no polling is done). Signed-off-by: Thomas Renninger <tr...@suse.de> --- src/comm.c | 3 ++- src/doc/screen.1 | 9 +++++++++ src/doc/screen.texinfo | 9 +++++++++ src/process.c | 12 ++++++++++++ src/screen.c | 7 +++++++ src/window.c | 29 ++++++++++++++++++++++++++++- src/window.h | 3 +++ 7 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/comm.c b/src/comm.c index 36b2270..8722ca8 100644 --- a/src/comm.c +++ b/src/comm.c @@ -339,5 +339,6 @@ struct comm comms[RC_LAST + 1] = #ifdef ZMODEM { "zmodem", ARGS_012 }, #endif - { "zombie", ARGS_012 } + { "zombie", ARGS_012 }, + { "zombie_timeout", ARGS_1 } }; diff --git a/src/doc/screen.1 b/src/doc/screen.1 index f27e84c..fc0d7ad 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -3542,6 +3542,15 @@ Optionally you can put the word \*Qonerror\*U after the keys. This will cause sc to monitor exit status of the process running in the window. If it exits normally ('0'), the window disappears. Any other exit value causes the window to become a zombie. +.BR "zombie_timeout" [\fIseconds\fP] +.PP +Per default +.I screen +windows are removed from the window list as soon as +the windows process (e.g. shell) exits. If \fBzombie\fP keys are defined +(compare with above \fBzombie\fP command), it is possible to also set a +timeout when screen tries to automatically reconnect a dead screen window. + .SH "THE MESSAGE LINE" .I Screen displays informational messages and other diagnostics in a \fImessage line\fP. diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index d721647..e564abe 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1237,6 +1237,8 @@ Send an XON character. @xref{XON/XOFF}. Define how screen treats zmodem requests. @xref{Zmodem}. @item zombie [@var{keys} [onerror] ] Keep dead windows. @xref{Zombie}. +@item zombie_timeout [@var{seconds}] +Try to reconnect dead windows after timeout. @xref{Zombie}. @end table @node New Window, Selecting, Commands, Top @@ -5219,6 +5221,8 @@ Display the version and modification date in the message line. @section Zombie @deffn Command zombie [@var{keys} [onerror] ] @deffnx Command defzombie [@var{keys}] +@deffn Command zombie_timeout [@var{seconds}] +@end deffn (none)@* Per default windows are removed from the window list as soon as the windows process (e.g. shell) exits. When a string of two keys is @@ -5238,6 +5242,11 @@ Optionally you can put the word @code{onerror} after the keys. This will cause screen to monitor exit status of the process running in the window. If it exits normally ('0'), the window disappears. Any other exit value causes the window to become a zombie. + +Additionally the @code{zombie_timeout} command exists. +If a window is declared ``dead'', screen will automatically try to +resurrect the window after the timeout. +It only works if zombie keys are defined via @code{zombie} command. @end deffn @node Printcmd, Rendition, Zombie, Miscellaneous diff --git a/src/process.c b/src/process.c index 783ada5..bbc46e6 100644 --- a/src/process.c +++ b/src/process.c @@ -3067,6 +3067,18 @@ int key; } WindowChanged((struct win *)0, 0); break; + case RC_ZOMBIE_TIMEOUT: + if (argc != 1) + { + Msg(0, "Setting zombie polling needs a timeout arg\n"); + break; + } + nwin_default.poll_zombie_timeout = atoi(args[0]); + if (fore) + fore->w_poll_zombie_timeout = nwin_default.poll_zombie_timeout; + + debug1("Setting zombie polling to %d\n", nwin_default.poll_zombie_timeout); + break; case RC_SILENCE: n = fore->w_silence != 0; i = fore->w_silencewait; diff --git a/src/screen.c b/src/screen.c index 6e19732..efb73d3 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1545,6 +1545,13 @@ int wstat_valid; p->w_y = MFindUsedLine(p, p->w_bot, 1); sprintf(buf, "\n\r=== Command %s (%s) ===", reason, s ? s : "?"); WriteString(p, buf, strlen(buf)); + if (p->w_poll_zombie_timeout) + { + debug2("Set zombie poll timeout for window %s to %d\n", p->w_title, + p->w_poll_zombie_timeout); + SetTimeout(&p->w_zombieev, p->w_poll_zombie_timeout * 1000); + evenq(&p->w_zombieev); + } WindowChanged(p, 'f'); } else diff --git a/src/window.c b/src/window.c index 1c6f5b6..47419e1 100644 --- a/src/window.c +++ b/src/window.c @@ -87,6 +87,7 @@ static int DoAutolf __P((char *, int *, int)); static void ZombieProcess __P((char **, int *)); static void win_readev_fn __P((struct event *, char *)); static void win_writeev_fn __P((struct event *, char *)); +static void win_resurrect_zombie_fn __P((struct event *, char *)); static int muchpending __P((struct win *, struct event *)); #ifdef COPY_PASTE static void paste_slowev_fn __P((struct event *, char *)); @@ -164,7 +165,8 @@ struct NewWindow nwin_default = 0, /* bce */ 0, /* encoding */ (char *)0, /* hstatus */ - (char *)0 /* charset */ + (char *)0, /* charset */ + 0 /* poll_zombie_timeout */ }; struct NewWindow nwin_options; @@ -198,6 +200,7 @@ struct NewWindow *def, *new, *res; COMPOSE(encoding); COMPOSE(hstatus); COMPOSE(charset); + COMPOSE(poll_zombie_timeout); #undef COMPOSE } @@ -831,6 +834,14 @@ struct NewWindow *newwin; DoStartLog(p, buf, sizeof(buf)); } + /* Is this all where I have to init window poll timeout? */ + if (nwin.poll_zombie_timeout) + p->w_poll_zombie_timeout = nwin.poll_zombie_timeout; + + p->w_zombieev.type = EV_TIMEOUT; + p->w_zombieev.data = (char *)p; + p->w_zombieev.handler = win_resurrect_zombie_fn; + p->w_readev.fd = p->w_writeev.fd = p->w_ptyfd; p->w_readev.type = EV_READ; p->w_writeev.type = EV_WRITE; @@ -1046,6 +1057,7 @@ struct win *wp; evdeq(&wp->w_readev); /* just in case */ evdeq(&wp->w_writeev); /* just in case */ evdeq(&wp->w_silenceev); + evdeq(&wp->w_zombieev); evdeq(&wp->w_destroyev); #ifdef COPY_PASTE FreePaster(&wp->w_paster); @@ -1937,6 +1949,21 @@ char *data; return; } +static void +win_resurrect_zombie_fn(ev, data) +struct event *ev; +char *data; +{ + struct win *p = (struct win *)data; + debug2("Try to resurrecting Zombie event: %d [%s]\n", + p->w_number, p->w_title); + /* Already reconnected? */ + if (p->w_deadpid != p->w_pid) + return; + debug1("Resurrecting Zombie: %d\n", p->w_number); + WriteString(p, "\r\n", 2); + RemakeWindow(p); +} static void win_writeev_fn(ev, data) diff --git a/src/window.h b/src/window.h index 7311ecb..380d3e9 100644 --- a/src/window.h +++ b/src/window.h @@ -57,6 +57,7 @@ struct NewWindow int encoding; char *hstatus; char *charset; + int poll_zombie_timeout; }; #ifdef PSEUDOS @@ -150,6 +151,8 @@ struct win struct event w_readev; struct event w_writeev; struct event w_silenceev; /* silence event */ + struct event w_zombieev; /* event to try to resurrect window */ + int w_poll_zombie_timeout; int w_ptyfd; /* fd of the master pty */ char w_inbuf[IOSIZE]; int w_inlen; -- 1.7.6.1 _______________________________________________ screen-users mailing list screen-users@gnu.org https://lists.gnu.org/mailman/listinfo/screen-users