[net.bugs.4bsd] 4.1 Bsd terminal handler improvements

sch@linus.UUCP (Stephen C. Hemminger) (06/14/83)

Subject: 4.1Bsd terminal handler improvements
Newsgroups: net.unix-wizards,net.bugs.4bsd

Here are two improvements to the terminal handler with 4.1Bsd Unix.
I am sending these out in the hope (albeit small) that they will
make it into 4.2 and future versions.

SYNOPSIS
     TIOCHPCL - clear hangup close bit

DESRCRIPTION
   Clears the hangup on last close bit.  As distributed to us, 4.1 Bsd has
an ioctl to set the hangup on last close bit, but none to clear it.

IMPLEMENTATION
   Mimic the TIOCHUPCL ioctl, only reset instead of set the bit.

--------------
SYNOPSIS
    TIOCDRAIN - wait for terminal output to drain

DESCRIPTION
   In 4.1 Bsd there is no way for a program to wait for all the output
to be sent to the terminal.  Games, editors and other programs which may
interact with the screen in a "real-time" fashion need this feature.
The best example is the Mitre/Rand screen editor which has a feature which
allows a user to scroll through a file and stop at any point by hitting a key.

(Note: the equivalent is present in USG Unix via TCSETW but the TIOCSETP ioctl
 clears the input buffers which is NOT wanted).

IMPLEMENTATION
   Copy over the drain routine from the already present routine wflushtty(),
but don't flush the input queues when done.


>>>>>>>>>>>>>>>>>>>> Diff of ioctl.h <<<<<<<<<<<<<<<<<<<<<<<<<

*** ioctl.h	Sat Jun 11 10:29:15 1983
--- ioctl.h.orig	Mon Jan 18 17:46:46 1982
***************
*** 84,87
  #define	TIOCSTI		(('t'<<8)|114)	/* simulate a terminal in character */
- #define	TIOCCHPCL	(('t'<<8)|113)	/* clear hangup line on close bit */
- #define	TIOCDRAIN	(('t'<<8)|112)	/* drain output buffer */
  

--- 84,85 -----
  #define	TIOCSTI		(('t'<<8)|114)	/* simulate a terminal in character */



>>>>>>>>>>>>>>>>>>> Diff of tty.c <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*** tty.c	Sat Jun 11 10:37:29 1983
--- tty.c.orig	Sun May 16 10:32:55 1982
***************
*** 96,106
  	(void) spl0();
  }
- #ifdef MITRE
- /*
-  * Wait for output to drain, but don't flush input queue
-  */
- draintty(tp)
- register struct tty *tp;
- {
  
  	(void) spl5();

--- 96,99 -----
  	(void) spl0();
  }
  
  /*
***************
*** 104,117
  {
  
- 	(void) spl5();
- 	while (tp->t_outq.c_cc && tp->t_state&CARR_ON) {
- 		(*tp->t_oproc)(tp);
- 		tp->t_state |= ASLEEP;
- 		sleep((caddr_t)&tp->t_outq, TTOPRI);
- 	}
- 	(void) spl0();
- }
- #endif
- 
  /*
   * flush all TTY queues

--- 97,100 -----
  }
  
  /*
   * flush all TTY queues
***************
*** 160,169
  		tp->t_state &= ~TBLOCK;
  	}
- #ifdef MITRE
- 	/*	We should only block if we aren't in that state already.
- 		We check for the blocked state before blocking, and
- 		don't block if we already have.	*/
-     if (!(tp->t_state & TBLOCK))
- #endif
  	if (x >= TTYHOG/2) {
  		if (putc(tun.t_stopc, &tp->t_outq)==0) {

--- 143,146 -----
  		tp->t_state &= ~TBLOCK;
  	}
  	if (x >= TTYHOG/2) {
  		if (putc(tun.t_stopc, &tp->t_outq)==0) {
***************
*** 528,553
  		break;
  /* end of locals */
- #ifdef MITRE
- /* start of mitre locals */
- 
- 	/*
- 	 * Do not hang up line on last close
- 	 */
- 	case TIOCCHPCL:
- 		tp->t_state &= ~HUPCLS;
- 		break;
- 
- 	/*
- 	 * new ioctl which waits for the output queue to drain,
- 	 *  programs which want to display data in semi-real time
- 	 *  without getting too far ahead of the user will want to
- 	 *  use this.
- 	 */
- 	case TIOCDRAIN:
- 		draintty(tp);
- 		break;
- 
- /* end of mitre locals */
- #endif
  
  	default:

--- 505,508 -----
  		break;
  /* end of locals */
  
  	default:

mark@cbosgd.UUCP (06/22/83)

Note that TIOCDRAIN can be emulated in 4.1BSD with TIOCOUTQ,
which returns the number of characters waiting in the queue.
You loop until it goes below the level you want (waiting until
zero may result in jerky output).  A high resolution sleep,
such as nap, or select, or the fast timer driver, helps.
TIOCOUTQ does not seem to be documented in 4.1 or 4.1c.