summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Naumov <posix.ru@gmail.com>2015-05-27 09:24:12 +0200
committerAlexander Naumov <posix.ru@gmail.com>2015-05-27 09:24:12 +0200
commit2e1bf9a3bf465761a0c0e38eb709835c64eeb260 (patch)
tree7e7154183355266f04c40efa82878735f646d703
parent7b72e98fc368e7facda37a1569d7aa0a85feafff (diff)
downloadscreen-2e1bf9a3bf465761a0c0e38eb709835c64eeb260.tar.gz
screen: Implement dead/zombie window polling
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: Alexander Naumov <posix.ru@gmail.com> Signed-off-by: Thomas Renninger <trenn@suse.de>
-rw-r--r--src/comm.c3
-rw-r--r--src/doc/screen.19
-rw-r--r--src/doc/screen.texinfo9
-rw-r--r--src/patchlevel.h8
-rw-r--r--src/process.c13
-rw-r--r--src/screen.c6
-rw-r--r--src/window.c29
-rw-r--r--src/window.h3
8 files changed, 74 insertions, 6 deletions
diff --git a/src/comm.c b/src/comm.c
index a086859..25779c9 100644
--- a/src/comm.c
+++ b/src/comm.c
@@ -337,5 +337,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 366ba40..c00af73 100644
--- a/src/doc/screen.1
+++ b/src/doc/screen.1
@@ -3547,6 +3547,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 c6ee63a..26aba8b 100644
--- a/src/doc/screen.texinfo
+++ b/src/doc/screen.texinfo
@@ -981,6 +981,8 @@ Set default line-wrapping behavior. @xref{Wrap}.
Set default writelock behavior. @xref{Multiuser Session}.
@item defzombie [@var{keys}]
Keep dead windows. @xref{Zombie}.
+@item zombie_timeout [@var{seconds}]
+Try to reconnect dead windows after timeout. @xref{Zombie}.
@item detach [-h]
Disconnect @code{screen} from the terminal. @xref{Detach}.
@item digraph [@var{preset} [@var{unicode-value}]]
@@ -5231,6 +5233,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
@@ -5250,6 +5254,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/patchlevel.h b/src/patchlevel.h
index 40661b9..0143e00 100644
--- a/src/patchlevel.h
+++ b/src/patchlevel.h
@@ -528,11 +528,11 @@
* 12.10.2004, 4.00.03jw1 let docu of 'split' 'focus' 'remove' and 'only' refer to each other.
* 01.11.2004, 4.00.03jw2 zombie command has new option 'onerror'
* 2005-12-19, 4.00.03jw3 syntax error.
- */
+*/
#define ORIGIN "GNU"
#define REV 4
-#define VERS 2
-#define PATCHLEVEL 1
-#define DATE "28-Apr-14"
+#define VERS 3
+#define PATCHLEVEL 0
+#define DATE "27-May-15"
#define STATE ""
diff --git a/src/process.c b/src/process.c
index 68cc7c9..8353098 100644
--- a/src/process.c
+++ b/src/process.c
@@ -3026,6 +3026,19 @@ int key;
}
}
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 deeafa1..ad798c5 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1559,6 +1559,12 @@ 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 c9d6817..f39f419 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 *));
@@ -139,7 +140,8 @@ struct NewWindow nwin_undef =
-1, /* bce */
-1, /* encoding */
(char *)0, /* hstatus */
- (char *)0 /* charset */
+ (char *)0, /* charset */
+ 0 /* poll_zombie_timeout */
};
struct NewWindow nwin_default =
@@ -198,6 +200,7 @@ struct NewWindow *def, *new, *res;
COMPOSE(encoding);
COMPOSE(hstatus);
COMPOSE(charset);
+ COMPOSE(poll_zombie_timeout);
#undef COMPOSE
}
@@ -835,6 +838,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;
@@ -1050,6 +1061,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);
@@ -1941,6 +1953,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;