diff --git a/screen-poll-zombies.patch b/screen-poll-zombies.patch new file mode 100644 index 0000000..7a958ae --- /dev/null +++ b/screen-poll-zombies.patch @@ -0,0 +1,243 @@ +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: Thomas Renninger + +--- + comm.c | 3 ++- + comm.h.dist | 3 ++- + doc/screen.1 | 9 +++++++++ + doc/screen.texinfo | 9 +++++++++ + process.c | 12 ++++++++++++ + screen.c | 7 +++++++ + window.c | 29 ++++++++++++++++++++++++++++- + window.h | 3 +++ + 8 files changed, 72 insertions(+), 3 deletions(-) + +Index: screen-4.0.4/comm.c +=================================================================== +--- screen-4.0.4.orig/comm.c ++++ screen-4.0.4/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 } + }; +Index: screen-4.0.4/doc/screen.1 +=================================================================== +--- screen-4.0.4.orig/doc/screen.1 ++++ screen-4.0.4/doc/screen.1 +@@ -3545,6 +3545,15 @@ Optionally you can put the word \*Qonerr + 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. +Index: screen-4.0.4/doc/screen.texinfo +=================================================================== +--- screen-4.0.4.orig/doc/screen.texinfo ++++ screen-4.0.4/doc/screen.texinfo +@@ -1238,6 +1238,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 +@@ -5222,6 +5224,8 @@ Display the version and modification dat + @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 +@@ -5241,6 +5245,11 @@ Optionally you can put the word @code{on + 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 +Index: screen-4.0.4/process.c +=================================================================== +--- screen-4.0.4.orig/process.c ++++ screen-4.0.4/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; +Index: screen-4.0.4/screen.c +=================================================================== +--- screen-4.0.4.orig/screen.c ++++ screen-4.0.4/screen.c +@@ -1557,6 +1557,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 +Index: screen-4.0.4/window.c +=================================================================== +--- screen-4.0.4.orig/window.c ++++ screen-4.0.4/window.c +@@ -87,6 +87,7 @@ static int DoAutolf __P((char *, 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 + } + +@@ -838,6 +841,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; +@@ -1060,6 +1071,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) +Index: screen-4.0.4/window.h +=================================================================== +--- screen-4.0.4.orig/window.h ++++ screen-4.0.4/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; +Index: screen-4.0.4/comm.h.dist +=================================================================== +--- screen-4.0.4.orig/comm.h.dist ++++ screen-4.0.4/comm.h.dist +@@ -236,5 +236,6 @@ struct action + #define RC_XON 179 + #define RC_ZMODEM 180 + #define RC_ZOMBIE 181 ++#define RC_ZOMBIE_TIMEOUT 182 + +-#define RC_LAST 181 ++#define RC_LAST 182 diff --git a/screen.changes b/screen.changes index b4c0c95..31a9857 100644 --- a/screen.changes +++ b/screen.changes @@ -1,3 +1,21 @@ +------------------------------------------------------------------- +Tue Feb 5 19:06:46 UTC 2013 - trenn@suse.de + +- Add zombie and enhance windows commands + screen-poll-zombies.patch: Dead windows will be restarted after + a specified timeout (if enabled) + screen_enhance_windows_list_1_3.patch: + Cleanup window flags processing. This leads to a slight + output change in "Ww" string escapes (window list), but these + should be rather seldom used and flags are still shown. + screen_enhance_windows_list_2_3.patch: + Enhance windows command with an optional string escape based + parameter which also removes the output size (1024 bytes) + restriction (only if param is passed) of the windows command. +- Only Require makeinfo for openSUSE versions 11.4 and above. + This requirement did not exist in earlier versions, now the package + builds again for example against SLES 11 (11.4 based). + ------------------------------------------------------------------- Thu Oct 25 13:11:20 UTC 2012 - trenn@suse.de diff --git a/screen.spec b/screen.spec index 4982644..90789bf 100644 --- a/screen.spec +++ b/screen.spec @@ -1,7 +1,7 @@ # # spec file for package screen # -# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,9 @@ Url: http://www.gnu.org/software/screen/ Name: screen +%if 0%{?suse_version} > 1140 BuildRequires: makeinfo +%endif BuildRequires: ncurses-devel %if 0%{?suse_version} > 1130 BuildRequires: utempter-devel @@ -46,6 +48,9 @@ Patch6: libtinfo.diff Patch7: mappedcmd.diff Patch8: styroptcrash.diff Patch9: use_locale.diff +Patch10: screen-poll-zombies.patch +Patch11: screen_enhance_windows_list_1_3.patch +Patch12: screen_enhance_windows_list_2_3.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -67,6 +72,9 @@ Documentation: man page %patch7 -p2 %patch8 -p2 %patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 %build CFLAGS="-DMAXWIN=1000 $RPM_OPT_FLAGS" %configure --prefix=/usr --infodir=%{_infodir} \ diff --git a/screen_enhance_windows_list_1_3.patch b/screen_enhance_windows_list_1_3.patch new file mode 100644 index 0000000..4e97b31 --- /dev/null +++ b/screen_enhance_windows_list_1_3.patch @@ -0,0 +1,60 @@ +screen: Remove foreground and other window marking workaround + +and place it where it always should have been in the generic AddWindowsFlag +function. + +The actual implementation when this workaround was added is beyond git +history. This was needed to implement a very specific String Escape (wW) +function: + w all window numbers and names. With '-' quailifier: up to the + current window; with '+' qualifier: starting with the window + after the current one. + + W all window numbers and names except the current one + +But adding all windows to a String Escape does not make much sense and +may only fit for a very specific special case. +Better clean up the code, whoever needed wW String Escapes can use windows +command nowadays. + +Later the whole wW String Escape should vanish in favor for the +String Escaped windows command which can do the same but much more flexible. + +Signed-off-by: Thomas Renninger + +Index: screen-4.0.4/process.c +=================================================================== +--- + src/process.c | 6 ------ + 1 files changed, 0 insertions(+), 6 deletions(-) + +diff --git a/process.c b/process.c +index bbc46e6..7370924 100644 +--- a/process.c ++++ b/process.c +@@ -5507,12 +5507,8 @@ int where; + AddWinMsgRend(s, rend); + sprintf(s, "%d", p->w_number); + s += strlen(s); +- if (display && p == D_fore) +- *s++ = '*'; + if (!(flags & 2)) + { +- if (display && p == D_other) +- *s++ = '-'; + s = AddWindowFlags(s, len, p); + } + *s++ = ' '; +@@ -5537,12 +5533,10 @@ struct win *p; + *s = 0; + return s; + } +-#if 0 + if (display && p == D_fore) + *s++ = '*'; + if (display && p == D_other) + *s++ = '-'; +-#endif + if (p->w_layer.l_cvlist && p->w_layer.l_cvlist->c_lnext) + *s++ = '&'; + if (p->w_monitor == MON_DONE diff --git a/screen_enhance_windows_list_2_3.patch b/screen_enhance_windows_list_2_3.patch new file mode 100644 index 0000000..7805e1f --- /dev/null +++ b/screen_enhance_windows_list_2_3.patch @@ -0,0 +1,140 @@ +screen: Introduce windows command + +This new command is doing nearly the same as the windows +command. +But a string escape can be passed which makes it much +more flexible. The default string escape if no argument +is passed is "%n%f %t " which is intended to rebuild +the same output the windows command would give as good +as possible (slight changes with the flags can happen). + +This command is also not be limited in output size +(the windows command is limited to 1024 bytes). + +The windowsx command can be queried (-Q command) and +this is its main purpose (be able to query the exact +window list status of an active screen session from +shell). + +Signed-off-by: Thomas Renninger +--- + src/comm.c | 2 +- + src/doc/screen.1 | 5 ++++- + src/doc/screen.texinfo | 7 ++++++- + src/process.c | 35 ++++++++++++++++++++++++++++++++++- + 4 files changed, 45 insertions(+), 4 deletions(-) + +diff --git a/comm.c b/comm.c +index 8722ca8..b8b535f 100644 +--- a/comm.c ++++ b/comm.c +@@ -328,7 +328,7 @@ struct comm comms[RC_LAST + 1] = + { "wall", NEED_DISPLAY|ARGS_1}, + { "width", ARGS_0123 }, + { "windowlist", ARGS_012 }, +- { "windows", CAN_QUERY|ARGS_0 }, ++ { "windows", CAN_QUERY|ARGS_01 }, + { "wrap", NEED_FORE|ARGS_01 }, + #ifdef COPY_PASTE + { "writebuf", ARGS_0123 }, +diff --git a/doc/screen.1 b/doc/screen.1 +index 4e72f8b..7a0c1de 100644 +--- a/doc/screen.1 ++++ b/doc/screen.1 +@@ -3430,7 +3430,7 @@ settings). + and 6 characters high in order to display. + .sp + .ne 3 +-.B windows ++.B windows [ string ] + .PP + Uses the message line to display a list of all the windows. + Each window is listed by number with the name of process that has been +@@ -3446,6 +3446,9 @@ windows occupied by other users are marked with `&'; + windows in the zombie state are marked with `Z'. + If this list is too long to fit on the terminal's status line only the + portion around the current window is displayed. ++The optional string parameter follows the \*QSTRING ESCAPES\*U format. ++If string parameter is passed, the output size is unlimited. ++The default command without any parameter is limited to a size of 1024 bytes. + .sp + .ne 3 + .BR "wrap " [ on | off ] +diff --git a/doc/screen.texinfo b/doc/screen.texinfo +index e564abe..e7a693d 100644 +--- a/doc/screen.texinfo ++++ b/doc/screen.texinfo +@@ -2613,7 +2613,7 @@ before displaying a message. Default is 30 seconds. + @section Windows + @kindex w + @kindex C-w +-@deffn Command windows ++@deffn Command windows [string] + (@kbd{C-a w}, @kbd{C-a C-w})@* + Uses the message line to display a list of all the windows. Each + window is listed by number with the name of the program running in the +@@ -2632,6 +2632,11 @@ windows in the zombie state are marked with @samp{Z}. + + If this list is too long to fit on the terminal's status line only the + portion around the current window is displayed. ++ ++You can customize the output format to any string you like including ++string escapes (@pxref{String Escapes}). ++In this case, if the string parameter is passed, the maximum output ++size is unlimited (instead of 1024 bytes if no parameter is passed). + @end deffn + + @node Hardstatus, Mousetrack, Windows, Window Settings +diff --git a/process.c b/process.c +index 7370924..79e82b5 100644 +--- a/process.c ++++ b/process.c +@@ -1838,7 +1838,12 @@ int key; + Activate(-1); + break; + case RC_WINDOWS: +- ShowWindows(-1); ++ if (args[0]) { ++ s = SaveStr(args[0]); ++ ShowWindowsX(s); ++ } ++ else ++ ShowWindows(-1); + break; + case RC_VERSION: + OutputMsg(0, "screen %s", version); +@@ -5605,6 +5610,34 @@ struct win *p; + return s; + } + ++/* ++ * String Escape based windows listing ++ * Unfortunately it is not possible to rebuild the exact ++ * output (flags) from ShowWindows() with a default ++ * string escape. But when there should be a new screen ++ * version where slight output changes get accepted, ++ * ShowWindowsX() should replace the rather static ++ * (in output and size) old ShowWindows() and AddWindows() ++ * functions ++ */ ++void ++ShowWindowsX(char *string) ++{ ++ int i; ++ char *s = ""; ++ ++ debug1("ShowWindowsX: string [%s]", string); ++ ++ for (i = 0; i < maxwin ; i++) ++ { ++ if (wtab[i] == NULL) ++ continue; ++ ++ s = MakeWinMsg(string, wtab[i], '%'); ++ Msg(0, "%s", s); ++ } ++} ++ + void + ShowWindows(where) + int where;