[comp.sources.bugs] Patch

earle@mahendo.Jpl.Nasa.Gov (Greg Earle) (05/24/89)

Haven't seen many `screen' related patches lately; here's my contribution:

This is a little patch for screen, which provides an enhancement for the
`w' subcommand, which displays a list of all the windows.  The normal
behavior is to show the number of the window, and show the command which
was *started* in that window.  That's all fine and dandy for people that
have complicated .screenrc files, and do wierd things like start up a
`telnet foo.com' in screen #2, etc.; but for yobbos like me, I just pop up
one window and create new shell windows (csh in my case) when necessary.
After a while, I had a problem: which window was that FTP running in?  What
about that rlogin to another machine?  And that Emacs for reading mail?
When I would use the `^A-w' command, all I would get would be `csh' for each
window.  I'd have to go to the window in question in order to see what was
actually running in it.  This got tiresome, so I decided to make use of
the BSD `w' command (thus the comment in the Summary: header) to get a
dynamic window process output from the ^A-w command.

As you might expect, it slows down seeing the output from ^A-w quite a lot,
since it has to open up a pipe, run `w' and then `awk' to parse the output.
But I've found that in practice, the slowdown is often not too bad and usually
is quite tolerable given the usefulness in return.

The only obvious problem with this patch will be that any pseudo-terminal
of screen's that has been idle for more than (or equal to) 10 days will not
show up in the output, because `w' lets the the idle output bleed into the
previous field if the idle output is 6 days (such as `10days').  Although in
this day and age of detached `screen' sessions, it certainly is possible; in
practice I don't anticipate that it will be a problem.	(^:

The bonus patch at the end corrects what I believe was a typo - all of the
pty's were allocated from ttyq0 on up instead of looking for the (usual case
of) next free ttypX (assuming the normal case where the ttyp[0-f] pty's are
not all allocated already).

Change the value (below) of MAXPTYS from 48 to your system limit if you use
more than the normal tty[pqr][0-f] range of pseudo terminals.

	- Greg Earle
	  Sun Microsystems, Inc.
	  earle@Sun.COM
	  earle@mahendo.JPL.NASA.GOV	(Guest)

-----------------------------  >8  Cut here  8<  -----------------------------

*** screen.c.orig	Sat May 20 22:07:32 1989
--- screen.c	Mon May 22 20:22:05 1989
***************
*** 44,49 ****
--- 44,50 ----
  
  #define MAXWIN     10
  #define MSGWAIT     5
+ #define MAXPTYS    48
  
  #define Ctrl(c) ((c)&037)
  
***************
*** 905,915 ****
--- 906,924 ----
      }
  }
  
+ struct { char tty[2]; char cmd[80]; } wbuf[MAXPTYS];
+ 
  static ShowWindows () {
      char buf[1024];
+     char *t;
      register char *s;
      register struct win **pp, *p;
+     register FILE *wstream;
+     int i, maxttysinuse;
  
+     wstream = popen("w -h -s | awk '{ print $2, $NF }'", "r");
+     for (i = 0; fscanf(wstream, "%s%s", wbuf[i].tty, wbuf[i].cmd) != EOF; i++);
+     maxttysinuse = i;
      for (s = buf, pp = wtab; pp < wtab+MAXWIN; ++pp) {
  	if ((p = *pp) == 0)
  	    continue;
***************
*** 924,930 ****
  	else if (p == other)
  	    *s++ = '-';
  	*s++ = ' ';
! 	strcpy (s, p->cmd);
  	s += strlen (s);
      }
      Msg (0, buf);
--- 933,948 ----
  	else if (p == other)
  	    *s++ = '-';
  	*s++ = ' ';
! 	strcpy (TtyName, TtyProto);
! 	for (t = TtyName, i = 0; *t != 'X'; ++t, ++i);
! 	for (i = 0; i <= maxttysinuse; i++) {
! 	    strncpy (t, wbuf[i].tty, 2);
! 	    if (strcmp (TtyName, p->tty) == 0) {
! 	        strcpy (s, wbuf[i].cmd);
! 		break;
! 	    }
! 	}
! /*	strcpy (s, p->cmd);	*/
  	s += strlen (s);
      }
      Msg (0, buf);
***************
*** 981,987 ****
      strcpy (PtyName, PtyProto);
      strcpy (TtyName, TtyProto);
      for (p = PtyName, i = 0; *p != 'X'; ++p, ++i) ;
!     for (l = "qpr"; *p = *l; ++l) {
  	for (d = "0123456789abcdef"; p[1] = *d; ++d) {
  	    if ((f = open (PtyName, O_RDWR)) != -1) {
  		TtyName[i] = p[0];
--- 999,1005 ----
      strcpy (PtyName, PtyProto);
      strcpy (TtyName, TtyProto);
      for (p = PtyName, i = 0; *p != 'X'; ++p, ++i) ;
!     for (l = "pqr"; *p = *l; ++l) {
  	for (d = "0123456789abcdef"; p[1] = *d; ++d) {
  	    if ((f = open (PtyName, O_RDWR)) != -1) {
  		TtyName[i] = p[0];

net@tub.UUCP (Oliver Laumann) (05/26/89)

In article <459@mahendo.Jpl.Nasa.Gov> earle@mahendo.JPL.NASA.GOV writes:
> The bonus patch at the end corrects what I believe was a typo - all of the
> pty's were allocated from ttyq0 on up instead of looking for the (usual case
> of) next free ttypX (assuming the normal case where the ttyp[0-f] pty's are
> not all allocated already).

This isn't a typo.  The reasons for the "qpr" search order were:

  1)  Certain implementations of telnet only allocate "p" ptys and
      therefore complain when all "p" ptys are used up by screen.

  2)  On many systems the "p" ptys are usually all in use (e.g.
      when the system is primarily accessed over terminal servers),
      so that the first free pty is (at least) a "q" pty anyway.
      Since "r" ptys are not always there, it seemed that the
      "qpr" search order would yield the highest "hit rate".

Anyway, since this is installation dependent, the seach order should
probably be configurable from the Makefile.

Regards,
--
    Oliver Laumann, Technical University of Berlin, Germany.
    ...!pyramid!tub!net   or   net@TUB.BITNET

net@tub.UUCP (Oliver Laumann) (05/26/89)

In article <459@mahendo.Jpl.Nasa.Gov> earle@mahendo.JPL.NASA.GOV writes:
> Haven't seen many `screen' related patches lately; here's my contribution:

There seem to be several problems with this patch.  I would have sent
this as a personal reply; but one of the problems is serious.

1)  A pipe to the "w" command is opened using "popen", but I don't
    see the corresponding pclose().

2)  Screen is usually installed as set-uid with owner root (e.g.
    to be able to call chown()).  Thus the "w" command must be
    started in a child process which properly resets it's uid
    (similar to the way the "hardcopy" files are created).

Regards,
    Oliver Laumann, Technical University of Berlin, Germany.
    ...!pyramid!tub!net   or   net@TUB.BITNET