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       |   14 ++++++++++++++
 src/doc/screen.texinfo |    9 +++++++++
 src/process.c          |   12 ++++++++++++
 src/screen.c           |    7 +++++++
 src/window.c           |   29 ++++++++++++++++++++++++++++-
 src/window.h           |    3 +++
 7 files changed, 75 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..4e72f8b 100644
--- a/src/doc/screen.1
+++ b/src/doc/screen.1
@@ -3542,6 +3542,20 @@ 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 re-launch the process that was
+running in the dead window. Best is to use this command in the .screenrc
+configuration file. If used during a running screen session, the default
+zombie_timeout polling variable for newly created windows in the future and
+the one in the current window (if available) will be changed to the new
+value.
+
 .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

Reply via email to