pty select() support
This commit is contained in:
parent
2713ed6cde
commit
0e3bef8597
3 changed files with 120 additions and 53 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <minix/com.h>
|
#include <minix/com.h>
|
||||||
#include <minix/callnr.h>
|
#include <minix/callnr.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
|
|
||||||
#if NR_PTYS > 0
|
#if NR_PTYS > 0
|
||||||
|
@ -51,6 +52,11 @@ typedef struct pty {
|
||||||
int ocount; /* # characters in the buffer */
|
int ocount; /* # characters in the buffer */
|
||||||
char *ohead, *otail; /* head and tail of the circular buffer */
|
char *ohead, *otail; /* head and tail of the circular buffer */
|
||||||
char obuf[128]; /* buffer for bytes going to the pty reader */
|
char obuf[128]; /* buffer for bytes going to the pty reader */
|
||||||
|
|
||||||
|
/* select() data. */
|
||||||
|
int select_ops, /* Which operations do we want to know about? */
|
||||||
|
select_proc, /* Who wants to know about it? */
|
||||||
|
select_ready_ops; /* For callback. */
|
||||||
} pty_t;
|
} pty_t;
|
||||||
|
|
||||||
#define PTY_ACTIVE 0x01 /* pty is open/active */
|
#define PTY_ACTIVE 0x01 /* pty is open/active */
|
||||||
|
@ -68,6 +74,7 @@ FORWARD _PROTOTYPE( int pty_read, (tty_t *tp, int try) );
|
||||||
FORWARD _PROTOTYPE( int pty_close, (tty_t *tp, int try) );
|
FORWARD _PROTOTYPE( int pty_close, (tty_t *tp, int try) );
|
||||||
FORWARD _PROTOTYPE( int pty_icancel, (tty_t *tp, int try) );
|
FORWARD _PROTOTYPE( int pty_icancel, (tty_t *tp, int try) );
|
||||||
FORWARD _PROTOTYPE( int pty_ocancel, (tty_t *tp, int try) );
|
FORWARD _PROTOTYPE( int pty_ocancel, (tty_t *tp, int try) );
|
||||||
|
FORWARD _PROTOTYPE( int pty_select, (tty_t *tp, message *m) );
|
||||||
|
|
||||||
|
|
||||||
/*==========================================================================*
|
/*==========================================================================*
|
||||||
|
@ -182,6 +189,10 @@ message *m_ptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DEV_SELECT:
|
||||||
|
r = pty_select(tp, m_ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
case CANCEL:
|
case CANCEL:
|
||||||
if (m_ptr->PROC_NR == pp->rdproc) {
|
if (m_ptr->PROC_NR == pp->rdproc) {
|
||||||
/* Cancel a read from a PTY. */
|
/* Cancel a read from a PTY. */
|
||||||
|
@ -215,6 +226,7 @@ int try;
|
||||||
int count, ocount, s;
|
int count, ocount, s;
|
||||||
phys_bytes user_phys;
|
phys_bytes user_phys;
|
||||||
|
|
||||||
|
|
||||||
/* PTY closed down? */
|
/* PTY closed down? */
|
||||||
if (pp->state & PTY_CLOSED) {
|
if (pp->state & PTY_CLOSED) {
|
||||||
if(try) return 1;
|
if(try) return 1;
|
||||||
|
@ -229,14 +241,12 @@ int try;
|
||||||
/* While there is something to do. */
|
/* While there is something to do. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ocount = buflen(pp->obuf) - pp->ocount;
|
ocount = buflen(pp->obuf) - pp->ocount;
|
||||||
|
if(try) return (ocount > 0);
|
||||||
count = bufend(pp->obuf) - pp->ohead;
|
count = bufend(pp->obuf) - pp->ohead;
|
||||||
if (count > ocount) count = ocount;
|
if (count > ocount) count = ocount;
|
||||||
if (count > tp->tty_outleft) count = tp->tty_outleft;
|
if (count > tp->tty_outleft) count = tp->tty_outleft;
|
||||||
if (count == 0 || tp->tty_inhibited) {
|
if (count == 0 || tp->tty_inhibited)
|
||||||
if(try) return 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if(try) return 1;
|
|
||||||
|
|
||||||
/* Copy from user space to the PTY output buffer. */
|
/* Copy from user space to the PTY output buffer. */
|
||||||
if((s = sys_vircopy(tp->tty_outproc, D, (vir_bytes) tp->tty_out_vir,
|
if((s = sys_vircopy(tp->tty_outproc, D, (vir_bytes) tp->tty_out_vir,
|
||||||
|
@ -339,7 +349,6 @@ pty_t *pp;
|
||||||
/* Finish the read request of a PTY reader if there is at least one byte
|
/* Finish the read request of a PTY reader if there is at least one byte
|
||||||
* transferred.
|
* transferred.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (pp->rdcum > 0) {
|
if (pp->rdcum > 0) {
|
||||||
if (pp->rdsendreply) {
|
if (pp->rdsendreply) {
|
||||||
tty_reply(TASK_REPLY, pp->rdcaller, pp->rdproc, pp->rdcum);
|
tty_reply(TASK_REPLY, pp->rdcaller, pp->rdproc, pp->rdcum);
|
||||||
|
@ -348,6 +357,7 @@ pty_t *pp;
|
||||||
else
|
else
|
||||||
notify(pp->rdcaller);
|
notify(pp->rdcaller);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,6 +374,7 @@ int try;
|
||||||
pty_t *pp = tp->tty_priv;
|
pty_t *pp = tp->tty_priv;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
|
|
||||||
if (pp->state & PTY_CLOSED) {
|
if (pp->state & PTY_CLOSED) {
|
||||||
if(try) return 1;
|
if(try) return 1;
|
||||||
if (tp->tty_inleft > 0) {
|
if (tp->tty_inleft > 0) {
|
||||||
|
@ -482,6 +493,7 @@ tty_t *tp;
|
||||||
line = tp - &tty_table[NR_CONS + NR_RS_LINES];
|
line = tp - &tty_table[NR_CONS + NR_RS_LINES];
|
||||||
pp = tp->tty_priv = &pty_table[line];
|
pp = tp->tty_priv = &pty_table[line];
|
||||||
pp->tty = tp;
|
pp->tty = tp;
|
||||||
|
pp->select_ops = 0;
|
||||||
|
|
||||||
/* Set up output queue. */
|
/* Set up output queue. */
|
||||||
pp->ohead = pp->otail = pp->obuf;
|
pp->ohead = pp->otail = pp->obuf;
|
||||||
|
@ -493,6 +505,7 @@ tty_t *tp;
|
||||||
tp->tty_icancel = pty_icancel;
|
tp->tty_icancel = pty_icancel;
|
||||||
tp->tty_ocancel = pty_ocancel;
|
tp->tty_ocancel = pty_ocancel;
|
||||||
tp->tty_close = pty_close;
|
tp->tty_close = pty_close;
|
||||||
|
tp->tty_select_ops = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -506,7 +519,7 @@ PUBLIC int pty_status(message *m_ptr)
|
||||||
|
|
||||||
event_found = 0;
|
event_found = 0;
|
||||||
for (i= 0, pp = pty_table; i<NR_PTYS; i++, pp++) {
|
for (i= 0, pp = pty_table; i<NR_PTYS; i++, pp++) {
|
||||||
if (((pp->state & TTY_CLOSED && pp->rdleft > 0) ||
|
if ((((pp->state & TTY_CLOSED) && pp->rdleft > 0) ||
|
||||||
pp->rdcum > 0) &&
|
pp->rdcum > 0) &&
|
||||||
pp->rdcaller == m_ptr->m_source)
|
pp->rdcaller == m_ptr->m_source)
|
||||||
{
|
{
|
||||||
|
@ -519,7 +532,7 @@ PUBLIC int pty_status(message *m_ptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((pp->state & TTY_CLOSED && pp->wrleft > 0) ||
|
if ((((pp->state & TTY_CLOSED) && pp->wrleft > 0) ||
|
||||||
pp->wrcum > 0) &&
|
pp->wrcum > 0) &&
|
||||||
pp->wrcaller == m_ptr->m_source)
|
pp->wrcaller == m_ptr->m_source)
|
||||||
{
|
{
|
||||||
|
@ -534,8 +547,79 @@ PUBLIC int pty_status(message *m_ptr)
|
||||||
event_found = 1;
|
event_found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pp->select_ready_ops && pp->select_proc == m_ptr->m_source) {
|
||||||
|
m_ptr->m_type = DEV_IO_READY;
|
||||||
|
m_ptr->DEV_MINOR = PTYPX_MINOR + i;
|
||||||
|
m_ptr->DEV_SEL_OPS = pp->select_ready_ops;
|
||||||
|
pp->select_ready_ops = 0;
|
||||||
|
event_found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return event_found;
|
return event_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*==========================================================================*
|
||||||
|
* select_try_pty *
|
||||||
|
*==========================================================================*/
|
||||||
|
PRIVATE int select_try_pty(tty_t *tp, int ops)
|
||||||
|
{
|
||||||
|
pty_t *pp = tp->tty_priv;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
if(ops & SEL_WR) {
|
||||||
|
/* Write won't block on error. */
|
||||||
|
if (pp->state & TTY_CLOSED) r |= SEL_WR;
|
||||||
|
else if (pp->wrleft != 0 || pp->wrcum != 0) r |= SEL_WR;
|
||||||
|
else r |= SEL_WR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ops & SEL_RD) {
|
||||||
|
/* Read won't block on error. */
|
||||||
|
if (pp->state & TTY_CLOSED) r |= SEL_RD;
|
||||||
|
else if(pp->rdleft != 0 || pp->rdcum != 0) r |= SEL_RD;
|
||||||
|
else if(pp->ocount > 0) r |= SEL_RD; /* Actual data. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==========================================================================*
|
||||||
|
* select_retry_pty *
|
||||||
|
*==========================================================================*/
|
||||||
|
PUBLIC void select_retry_pty(tty_t *tp)
|
||||||
|
{
|
||||||
|
pty_t *pp = tp->tty_priv;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* See if the pty side of a pty is ready to return a select. */
|
||||||
|
if(pp->select_ops && (r=select_try_pty(tp, pp->select_ops))) {
|
||||||
|
pp->select_ops &= ~r;
|
||||||
|
pp->select_ready_ops |= r;
|
||||||
|
notify(pp->select_proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==========================================================================*
|
||||||
|
* pty_select *
|
||||||
|
*==========================================================================*/
|
||||||
|
PRIVATE int pty_select(tty_t *tp, message *m)
|
||||||
|
{
|
||||||
|
pty_t *pp = tp->tty_priv;
|
||||||
|
int ops, ready_ops = 0, watch;
|
||||||
|
|
||||||
|
ops = m->PROC_NR & (SEL_RD|SEL_WR|SEL_ERR);
|
||||||
|
watch = (m->PROC_NR & SEL_NOTIFY) ? 1 : 0;
|
||||||
|
|
||||||
|
ready_ops = select_try_pty(tp, ops);
|
||||||
|
|
||||||
|
if(!ready_ops && ops && watch) {
|
||||||
|
pp->select_ops |= ops;
|
||||||
|
pp->select_proc = m->m_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ready_ops;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* NR_PTYS > 0 */
|
#endif /* NR_PTYS > 0 */
|
||||||
|
|
|
@ -82,15 +82,9 @@ unsigned long rs_irq_set = 0;
|
||||||
/* Address of a tty structure. */
|
/* Address of a tty structure. */
|
||||||
#define tty_addr(line) (&tty_table[line])
|
#define tty_addr(line) (&tty_table[line])
|
||||||
|
|
||||||
/* First minor numbers for the various classes of TTY devices. */
|
|
||||||
#define CONS_MINOR 0
|
|
||||||
#define LOG_MINOR 15
|
|
||||||
#define RS232_MINOR 16
|
|
||||||
#define TTYPX_MINOR 128
|
|
||||||
#define PTYPX_MINOR 192
|
|
||||||
|
|
||||||
/* Macros for magic tty types. */
|
/* Macros for magic tty types. */
|
||||||
#define isconsole(tp) ((tp) < tty_addr(NR_CONS))
|
#define isconsole(tp) ((tp) < tty_addr(NR_CONS))
|
||||||
|
#define ispty(tp) ((tp) >= tty_addr(NR_CONS+NR_RS_LINES))
|
||||||
|
|
||||||
/* Macros for magic tty structure pointers. */
|
/* Macros for magic tty structure pointers. */
|
||||||
#define FIRST_TTY tty_addr(0)
|
#define FIRST_TTY tty_addr(0)
|
||||||
|
@ -181,7 +175,6 @@ PUBLIC void main(void)
|
||||||
panic("TTY","Couldn't obtain kernel environment.", s);
|
panic("TTY","Couldn't obtain kernel environment.", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
|
||||||
/* Check for and handle any events on any of the ttys. */
|
/* Check for and handle any events on any of the ttys. */
|
||||||
|
@ -476,11 +469,8 @@ register message *m_ptr; /* pointer to message sent to the task */
|
||||||
|
|
||||||
/* Try to write. */
|
/* Try to write. */
|
||||||
handle_events(tp);
|
handle_events(tp);
|
||||||
if (tp->tty_outleft == 0) {
|
if (tp->tty_outleft == 0)
|
||||||
if(tp->tty_select_ops)
|
|
||||||
select_retry(tp);
|
|
||||||
return; /* already done */
|
return; /* already done */
|
||||||
}
|
|
||||||
|
|
||||||
/* None or not all the bytes could be written, so either suspend the
|
/* None or not all the bytes could be written, so either suspend the
|
||||||
* caller or break off the write if nonblocking.
|
* caller or break off the write if nonblocking.
|
||||||
|
@ -494,8 +484,6 @@ register message *m_ptr; /* pointer to message sent to the task */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, r);
|
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, r);
|
||||||
if(tp->tty_select_ops)
|
|
||||||
select_retry(tp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -807,7 +795,6 @@ PUBLIC int select_try(struct tty *tp, int ops)
|
||||||
* (and it can be seen as an exceptional condition.)
|
* (and it can be seen as an exceptional condition.)
|
||||||
*/
|
*/
|
||||||
if (tp->tty_termios.c_ospeed == B0) {
|
if (tp->tty_termios.c_ospeed == B0) {
|
||||||
printf("tty: hangup always ok\n");
|
|
||||||
ready_ops |= ops;
|
ready_ops |= ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,8 +803,8 @@ PUBLIC int select_try(struct tty *tp, int ops)
|
||||||
if (tp->tty_inleft > 0) {
|
if (tp->tty_inleft > 0) {
|
||||||
ready_ops |= SEL_RD; /* EIO - no blocking */
|
ready_ops |= SEL_RD; /* EIO - no blocking */
|
||||||
} else if(tp->tty_incount > 0) {
|
} else if(tp->tty_incount > 0) {
|
||||||
/* is a regular read possible? tty_incount
|
/* Is a regular read possible? tty_incount
|
||||||
* says there is data. but a read will only succeed
|
* says there is data. But a read will only succeed
|
||||||
* in canonical mode if a newline has been seen.
|
* in canonical mode if a newline has been seen.
|
||||||
*/
|
*/
|
||||||
if(!(tp->tty_termios.c_lflag & ICANON) ||
|
if(!(tp->tty_termios.c_lflag & ICANON) ||
|
||||||
|
@ -828,12 +815,8 @@ PUBLIC int select_try(struct tty *tp, int ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ops & SEL_WR) {
|
if(ops & SEL_WR) {
|
||||||
if (tp->tty_outleft > 0) {
|
if (tp->tty_outleft > 0) ready_ops |= SEL_WR;
|
||||||
ready_ops |= SEL_WR; /* EIO - no blocking */
|
else if((*tp->tty_devwrite)(tp, 1)) ready_ops |= SEL_WR;
|
||||||
}
|
|
||||||
if((*tp->tty_devwrite)(tp, 1)) {
|
|
||||||
ready_ops |= SEL_WR; /* real write possible */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ready_ops;
|
return ready_ops;
|
||||||
|
@ -841,21 +824,8 @@ PUBLIC int select_try(struct tty *tp, int ops)
|
||||||
|
|
||||||
PUBLIC int select_retry(struct tty *tp)
|
PUBLIC int select_retry(struct tty *tp)
|
||||||
{
|
{
|
||||||
#if DEAD_CODE
|
|
||||||
int ops;
|
|
||||||
if((ops = select_try(tp, tp->tty_select_ops))) {
|
|
||||||
message m;
|
|
||||||
m.NOTIFY_TYPE = DEV_SELECTED;
|
|
||||||
m.NOTIFY_ARG = tp->tty_index;
|
|
||||||
m.NOTIFY_FLAGS = ops;
|
|
||||||
notify(tp->tty_select_proc, &m);
|
|
||||||
tp->tty_select_ops &= ~ops;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (select_try(tp, tp->tty_select_ops))
|
if (select_try(tp, tp->tty_select_ops))
|
||||||
notify(tp->tty_select_proc);
|
notify(tp->tty_select_proc);
|
||||||
#endif
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,6 +885,10 @@ tty_t *tp; /* TTY to check for events. */
|
||||||
tp->tty_inleft = tp->tty_incum = 0;
|
tp->tty_inleft = tp->tty_incum = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if(tp->tty_select_ops)
|
||||||
|
select_retry(tp);
|
||||||
|
if(ispty(tp))
|
||||||
|
select_retry_pty(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1559,11 +1533,14 @@ PRIVATE void tty_init()
|
||||||
tty_devnop;
|
tty_devnop;
|
||||||
if (tp < tty_addr(NR_CONS)) {
|
if (tp < tty_addr(NR_CONS)) {
|
||||||
scr_init(tp);
|
scr_init(tp);
|
||||||
|
tp->tty_minor = CONS_MINOR + s;
|
||||||
} else
|
} else
|
||||||
if (tp < tty_addr(NR_CONS+NR_RS_LINES)) {
|
if (tp < tty_addr(NR_CONS+NR_RS_LINES)) {
|
||||||
rs_init(tp);
|
rs_init(tp);
|
||||||
|
tp->tty_minor = RS232_MINOR + s-NR_CONS;
|
||||||
} else {
|
} else {
|
||||||
pty_init(tp);
|
pty_init(tp);
|
||||||
|
tp->tty_minor = s + TTYPX_MINOR + s-(NR_CONS+RS232_MINOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1671,7 +1648,6 @@ register tty_t *tp; /* pointer to tty struct */
|
||||||
register message *m_ptr; /* pointer to message sent to the task */
|
register message *m_ptr; /* pointer to message sent to the task */
|
||||||
{
|
{
|
||||||
int ops, ready_ops = 0, watch;
|
int ops, ready_ops = 0, watch;
|
||||||
printf("doing select..\n");
|
|
||||||
|
|
||||||
ops = m_ptr->PROC_NR & (SEL_RD|SEL_WR|SEL_ERR);
|
ops = m_ptr->PROC_NR & (SEL_RD|SEL_WR|SEL_ERR);
|
||||||
watch = (m_ptr->PROC_NR & SEL_NOTIFY) ? 1 : 0;
|
watch = (m_ptr->PROC_NR & SEL_NOTIFY) ? 1 : 0;
|
||||||
|
@ -1679,11 +1655,9 @@ register message *m_ptr; /* pointer to message sent to the task */
|
||||||
ready_ops = select_try(tp, ops);
|
ready_ops = select_try(tp, ops);
|
||||||
|
|
||||||
if(!ready_ops && ops && watch) {
|
if(!ready_ops && ops && watch) {
|
||||||
printf("doing select.. ops %d\n", ops);
|
|
||||||
tp->tty_select_ops |= ops;
|
tp->tty_select_ops |= ops;
|
||||||
tp->tty_select_proc = m_ptr->m_source;
|
tp->tty_select_proc = m_ptr->m_source;
|
||||||
} else printf("not doing select.. ready_ops %d ops %d watch %d\n",
|
}
|
||||||
ready_ops, ops, watch);
|
|
||||||
|
|
||||||
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, ready_ops);
|
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, ready_ops);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
#include <timers.h>
|
#include <timers.h>
|
||||||
|
|
||||||
|
/* First minor numbers for the various classes of TTY devices. */
|
||||||
|
#define CONS_MINOR 0
|
||||||
|
#define LOG_MINOR 15
|
||||||
|
#define RS232_MINOR 16
|
||||||
|
#define TTYPX_MINOR 128
|
||||||
|
#define PTYPX_MINOR 192
|
||||||
|
|
||||||
#define LINEWRAP 1 /* console.c - wrap lines at column 80 */
|
#define LINEWRAP 1 /* console.c - wrap lines at column 80 */
|
||||||
|
|
||||||
#define TTY_IN_BYTES 256 /* tty input queue size */
|
#define TTY_IN_BYTES 256 /* tty input queue size */
|
||||||
|
@ -20,6 +27,7 @@ typedef _PROTOTYPE( void (*devfunarg_t), (struct tty *tp, int c) );
|
||||||
typedef struct tty {
|
typedef struct tty {
|
||||||
int tty_events; /* set when TTY should inspect this line */
|
int tty_events; /* set when TTY should inspect this line */
|
||||||
int tty_index; /* index into TTY table */
|
int tty_index; /* index into TTY table */
|
||||||
|
int tty_minor; /* device minor number */
|
||||||
|
|
||||||
/* Input queue. Typed characters are stored here until read by a program. */
|
/* Input queue. Typed characters are stored here until read by a program. */
|
||||||
u16_t *tty_inhead; /* pointer to place where next char goes */
|
u16_t *tty_inhead; /* pointer to place where next char goes */
|
||||||
|
@ -156,6 +164,7 @@ _PROTOTYPE( void kbd_interrupt, (message *m) );
|
||||||
/* pty.c */
|
/* pty.c */
|
||||||
_PROTOTYPE( void do_pty, (struct tty *tp, message *m_ptr) );
|
_PROTOTYPE( void do_pty, (struct tty *tp, message *m_ptr) );
|
||||||
_PROTOTYPE( void pty_init, (struct tty *tp) );
|
_PROTOTYPE( void pty_init, (struct tty *tp) );
|
||||||
|
_PROTOTYPE( void select_retry_pty, (struct tty *tp) );
|
||||||
_PROTOTYPE( int pty_status, (message *m_ptr) );
|
_PROTOTYPE( int pty_status, (message *m_ptr) );
|
||||||
|
|
||||||
/* vidcopy.s */
|
/* vidcopy.s */
|
||||||
|
|
Loading…
Reference in a new issue