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.