* TTY subroutines common to more than one line discipline
* When running dz's using only SAE (silo alarm) on input
* it is necessary to call dzrint() at clock interrupt time.
* This is unsafe unless spl5()s in tty code are changed to
* spl6()s to block clock interrupts. Note that the dh driver
* currently in use works the same way as the dz, even though
* we could try to more intelligently manage its silo.
* Thus don't take this out if you have no dz's unless you
* change clock.c and dhtimer().
* Input mapping table-- if an entry is non-zero, when the
* corresponding character is typed preceded by "\" the escape
* sequence is replaced by the table value. Mostly used for
* upper-case only terminals.
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,'|',000,000,000,000,000,'`',
'{','}',000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,
000,000,000,000,000,000,'~',000,
000,'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W',
'X','Y','Z',000,000,000,000,000,
{ 100,100,100,100,100,100,100,200,200,400,400,400,650,650,650,650 };
{ 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
* set default control characters.
* Wait for output to drain, then flush input waiting.
while (tp
->t_outq
.c_cc
&& tp
->t_state
&CARR_ON
) {
sleep((caddr_t
)&tp
->t_outq
, TTOPRI
);
flushtty(tp
, FREAD
|FWRITE
);
if (tp
->t_line
== NETLDISC
)
while (getc(&tp
->t_canq
) >= 0)
wakeup((caddr_t
)&tp
->t_rawq
);
wakeup((caddr_t
)&tp
->t_outq
);
(*cdevsw
[major(tp
->t_dev
)].d_stop
)(tp
);
while (getc(&tp
->t_outq
) >= 0)
while (getc(&tp
->t_rawq
) >= 0)
tp
->t_rocount
= 0; /* local */
* Send stop character on input overflow.
x
= tp
->t_rawq
.c_cc
+ tp
->t_canq
.c_cc
;
if (tp
->t_rawq
.c_cc
> TTYHOG
) {
flushtty(tp
, FREAD
|FWRITE
);
if (putc(tun
.t_stopc
, &tp
->t_outq
)==0) {
* Restart typewriter output following a delay
* The name of the routine is passed to the timeout
* subroutine and it is called during a clock interrupt.
* Start output on the typewriter. It is used from the top half
* after some characters have been put on the output queue,
* from the interrupt routine to transmit the next
* character, and after a timeout has finished.
if((tp
->t_state
&(TIMEOUT
|TTSTOP
|BUSY
)) == 0)
* Common code for tty ioctls.
ttioctl(com
, tp
, addr
, dev
, flag
)
* This is especially so that isatty() will
* fail when carrier is gone.
if ((tp
->t_state
&CARR_ON
) == 0) {
* If the ioctl involves modification,
* insist on being able to write the device,
* and hang if in the background.
/* this is reasonable, but impractical...
if ((flag & FWRITE) == 0) {
while (tp
->t_line
== NTTYDISC
&&
u
.u_procp
->p_pgrp
!= tp
->t_pgrp
&& tp
== u
.u_ttyp
&&
(u
.u_procp
->p_flag
&SVFORK
) == 0 &&
u
.u_signal
[SIGTTOU
] != SIG_IGN
&&
u
.u_signal
[SIGTTOU
] != SIG_HOLD
&&
(u
.u_procp
->p_flag
&SDETACH
)==0) {
gsignal(u
.u_procp
->p_pgrp
, SIGTTOU
);
sleep((caddr_t
)&lbolt
, TTOPRI
);
if (copyout((caddr_t
)&t
, addr
, sizeof(t
)))
if (copyin(addr
, (caddr_t
)&t
, sizeof(t
))) {
(*linesw
[tp
->t_line
].l_close
)(tp
);
(*linesw
[t
].l_open
)(dev
, tp
, addr
);
* Prevent more opens on channel
if (copyin(addr
, (caddr_t
)&iocb
, sizeof(iocb
))) {
} else if (tp
->t_line
== NTTYDISC
) {
if (tp
->t_flags
&RAW
|| iocb
.sg_flags
&RAW
||
else if ((tp
->t_flags
&CBREAK
) != (iocb
.sg_flags
&CBREAK
)) {
if (iocb
.sg_flags
& CBREAK
) {
catq(&tp
->t_rawq
, &tp
->t_canq
);
(void) sdata(tp
->t_chan
);
wakeup((caddr_t
)&tp
->t_rawq
);
if ((tp
->t_state
&SPEEDS
)==0) {
tp
->t_ispeed
= iocb
.sg_ispeed
;
tp
->t_ospeed
= iocb
.sg_ospeed
;
tp
->t_erase
= iocb
.sg_erase
;
tp
->t_kill
= iocb
.sg_kill
;
tp
->t_flags
= iocb
.sg_flags
;
* Send current parameters to user
iocb
.sg_ispeed
= tp
->t_ispeed
;
iocb
.sg_ospeed
= tp
->t_ospeed
;
iocb
.sg_erase
= tp
->t_erase
;
iocb
.sg_kill
= tp
->t_kill
;
iocb
.sg_flags
= tp
->t_flags
;
if (copyout((caddr_t
)&iocb
, addr
, sizeof(iocb
)))
* Hang up line on last close
flushtty(tp
, FREAD
|FWRITE
);
* Ioctl entries to line discipline
if ((*linesw
[tp
->t_line
].l_ioctl
)(com
, tp
, addr
))
* Set and fetch special characters
if (copyin(addr
, (caddr_t
)&tun
, sizeof(struct tchars
)))
if (copyout((caddr_t
)&tun
, addr
, sizeof(struct tchars
)))
* Set/get local special characters.
if (copyin(addr
, (caddr_t
)&tlun
, sizeof (struct ltchars
)))
if (copyout((caddr_t
)&tlun
, addr
, sizeof (struct ltchars
)))
* Return number of characters immediately available.
nread
= tp
->t_rec
? tp
->t_inbuf
: 0;
if (tp
->t_flags
& (RAW
|CBREAK
))
nread
+= tp
->t_rawq
.c_cc
;
if (copyout((caddr_t
)&nread
, addr
, sizeof (off_t
)))
* Should allow SPGRP and GPGRP only if tty open for reading.
if (copyin(addr
, (caddr_t
)&tp
->t_pgrp
, sizeof (tp
->t_pgrp
)))
if (copyout((caddr_t
)&tp
->t_pgrp
, addr
, sizeof(tp
->t_pgrp
)))
* Modify local mode word.
if (copyin(addr
, (caddr_t
)&temp
, sizeof (tp
->t_local
)))
if (copyin(addr
, (caddr_t
)&temp
, sizeof (tp
->t_local
)))
if (copyin(addr
, (caddr_t
)&temp
, sizeof (tp
->t_local
)))
if (copyout((caddr_t
)&tp
->t_local
, addr
, sizeof(tp
->t_local
)))
* Return number of characters in
if (copyout((caddr_t
)&tp
->t_outq
.c_cc
, addr
, sizeof(tp
->t_outq
.c_cc
)))
* Simulate typing of a character at the terminal.
if (u
.u_uid
&& u
.u_ttyp
!= tp
|| c
< 0)
(*linesw
[tp
->t_line
].l_rint
)(c
, tp
);