. Safe I/O, ioctl() and DIAGNOSTICS variants conversion - safe copies,
include grant id in DEV_REVIVE messages. . Removal of TTY_FLAGS field (and so O_NONBLOCK support). . Fixed CANCEL behaviour and return code on blocking I/O, previously handled by O_NONBLOCK . Totally removed REVIVE replies, previously still possible on blocking ioctls (REVIVE directly called) and ptys (missing TTY_REVIVE check), removes deadlock bug with FS . Removed obsolete *COMPAT options and associated code
This commit is contained in:
parent
9fa06d5e3f
commit
1c8b206a5d
@ -14,7 +14,7 @@ MAKE = exec make
|
|||||||
CC = exec cc
|
CC = exec cc
|
||||||
CFLAGS = -I$i
|
CFLAGS = -I$i
|
||||||
LDFLAGS = -i
|
LDFLAGS = -i
|
||||||
LIBS = -lsys -lsysutil -ltimers
|
LIBS = -lsysutil -lsys -ltimers
|
||||||
|
|
||||||
OBJ = tty.o console.o vidcopy.o keyboard.o pty.o rs232.o
|
OBJ = tty.o console.o vidcopy.o keyboard.o pty.o rs232.o
|
||||||
|
|
||||||
|
|||||||
@ -167,13 +167,20 @@ int try;
|
|||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
if (count > sizeof(buf)) count = sizeof(buf);
|
if (count > sizeof(buf)) count = sizeof(buf);
|
||||||
if ((result = sys_vircopy(tp->tty_outproc, D, tp->tty_out_vir,
|
if(tp->tty_out_safe) {
|
||||||
|
if ((result = sys_safecopyfrom(tp->tty_outproc, tp->tty_out_vir_g,
|
||||||
|
tp->tty_out_vir_offset, (vir_bytes) buf, count, D)) != OK)
|
||||||
|
break;
|
||||||
|
tp->tty_out_vir_offset += count;
|
||||||
|
} else {
|
||||||
|
if ((result = sys_vircopy(tp->tty_outproc, D, tp->tty_out_vir_g,
|
||||||
SELF, D, (vir_bytes) buf, (vir_bytes) count)) != OK)
|
SELF, D, (vir_bytes) buf, (vir_bytes) count)) != OK)
|
||||||
break;
|
break;
|
||||||
|
tp->tty_out_vir_g += count;
|
||||||
|
}
|
||||||
tbuf = buf;
|
tbuf = buf;
|
||||||
|
|
||||||
/* Update terminal data structure. */
|
/* Update terminal data structure. */
|
||||||
tp->tty_out_vir += count;
|
|
||||||
tp->tty_outcum += count;
|
tp->tty_outcum += count;
|
||||||
tp->tty_outleft -= count;
|
tp->tty_outleft -= count;
|
||||||
|
|
||||||
@ -777,7 +784,7 @@ PRIVATE void beep()
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void do_video(message *m)
|
PUBLIC void do_video(message *m)
|
||||||
{
|
{
|
||||||
int i, n, r, ops, watch;
|
int i, n, r, ops, watch, safe = 0;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
||||||
/* Execute the requested device driver function. */
|
/* Execute the requested device driver function. */
|
||||||
@ -790,6 +797,9 @@ PUBLIC void do_video(message *m)
|
|||||||
case DEV_CLOSE:
|
case DEV_CLOSE:
|
||||||
r= OK;
|
r= OK;
|
||||||
break;
|
break;
|
||||||
|
case DEV_IOCTL_S:
|
||||||
|
safe=1;
|
||||||
|
/* Fallthrough. */
|
||||||
case DEV_IOCTL:
|
case DEV_IOCTL:
|
||||||
if (m->TTY_REQUEST == MIOCMAP || m->TTY_REQUEST == MIOCUNMAP)
|
if (m->TTY_REQUEST == MIOCMAP || m->TTY_REQUEST == MIOCUNMAP)
|
||||||
{
|
{
|
||||||
@ -799,18 +809,30 @@ PUBLIC void do_video(message *m)
|
|||||||
do_map= (m->REQUEST == MIOCMAP); /* else unmap */
|
do_map= (m->REQUEST == MIOCMAP); /* else unmap */
|
||||||
|
|
||||||
/* Get request structure */
|
/* Get request structure */
|
||||||
r= sys_vircopy(m->IO_ENDPT, D,
|
if(safe) {
|
||||||
|
r = sys_safecopyfrom(m->IO_ENDPT,
|
||||||
|
(vir_bytes)m->ADDRESS, 0, (vir_bytes) &mapreq,
|
||||||
|
sizeof(mapreq), D);
|
||||||
|
} else {
|
||||||
|
r= sys_vircopy(m->IO_ENDPT, D,
|
||||||
(vir_bytes)m->ADDRESS,
|
(vir_bytes)m->ADDRESS,
|
||||||
SELF, D, (vir_bytes)&mapreq, sizeof(mapreq));
|
SELF, D, (vir_bytes)&mapreq, sizeof(mapreq));
|
||||||
|
}
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
{
|
{
|
||||||
tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT,
|
tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT,
|
||||||
r);
|
r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
r= sys_vm_map(m->IO_ENDPT, do_map,
|
|
||||||
(phys_bytes)mapreq.base, mapreq.size,
|
/* In safe ioctl mode, the POSITION field contains
|
||||||
mapreq.offset);
|
* the endpt number of the original requestor.
|
||||||
|
* IO_ENDPT is always FS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
r= sys_vm_map(safe ? m->POSITION : m->IO_ENDPT,
|
||||||
|
do_map, (phys_bytes)mapreq.base, mapreq.size,
|
||||||
|
mapreq.offset);
|
||||||
tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT, r);
|
tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1057,20 +1079,27 @@ message *m;
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_diagnostics *
|
* do_diagnostics *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void do_diagnostics(m_ptr)
|
PUBLIC void do_diagnostics(m_ptr, safe)
|
||||||
message *m_ptr; /* pointer to request message */
|
message *m_ptr; /* pointer to request message */
|
||||||
|
int safe;
|
||||||
{
|
{
|
||||||
/* Print a string for a server. */
|
/* Print a string for a server. */
|
||||||
char c;
|
char c;
|
||||||
vir_bytes src;
|
vir_bytes src;
|
||||||
int count;
|
int count, offset = 0;
|
||||||
int result = OK;
|
int result = OK;
|
||||||
int proc_nr = m_ptr->DIAG_ENDPT;
|
int proc_nr = m_ptr->m_source;
|
||||||
if (proc_nr == SELF) proc_nr = m_ptr->m_source;
|
|
||||||
|
|
||||||
src = (vir_bytes) m_ptr->DIAG_PRINT_BUF;
|
src = (vir_bytes) m_ptr->DIAG_PRINT_BUF_G;
|
||||||
for (count = m_ptr->DIAG_BUF_COUNT; count > 0; count--) {
|
for (count = m_ptr->DIAG_BUF_COUNT; count > 0; count--) {
|
||||||
if (sys_vircopy(proc_nr, D, src++, SELF, D, (vir_bytes) &c, 1) != OK) {
|
int r;
|
||||||
|
if(safe) {
|
||||||
|
r = sys_safecopyfrom(proc_nr, src, offset, (vir_bytes) &c, 1, D);
|
||||||
|
} else {
|
||||||
|
r = sys_vircopy(proc_nr, D, src+offset, SELF, D, (vir_bytes) &c, 1);
|
||||||
|
}
|
||||||
|
offset++;
|
||||||
|
if(r != OK) {
|
||||||
result = EFAULT;
|
result = EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,7 +110,9 @@ PRIVATE struct kbd
|
|||||||
int avail;
|
int avail;
|
||||||
int req_size;
|
int req_size;
|
||||||
int req_proc;
|
int req_proc;
|
||||||
vir_bytes req_addr;
|
int req_safe; /* nonzero: safe (req_addr_g is grant) */
|
||||||
|
vir_bytes req_addr_g; /* Virtual address or grant */
|
||||||
|
vir_bytes req_addr_offset;
|
||||||
int incaller;
|
int incaller;
|
||||||
int select_ops;
|
int select_ops;
|
||||||
int select_proc;
|
int select_proc;
|
||||||
@ -188,7 +190,7 @@ PRIVATE void handle_req(kbdp, m)
|
|||||||
struct kbd *kbdp;
|
struct kbd *kbdp;
|
||||||
message *m;
|
message *m;
|
||||||
{
|
{
|
||||||
int i, n, r, ops, watch;
|
int i, n, r, ops, watch, safecopy = 0;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
|
||||||
/* Execute the requested device driver function. */
|
/* Execute the requested device driver function. */
|
||||||
@ -209,6 +211,9 @@ message *m;
|
|||||||
kbdp->avail= 0;
|
kbdp->avail= 0;
|
||||||
r= OK;
|
r= OK;
|
||||||
break;
|
break;
|
||||||
|
case DEV_READ_S:
|
||||||
|
safecopy = 1;
|
||||||
|
/* Fallthrough. */
|
||||||
case DEV_READ:
|
case DEV_READ:
|
||||||
if (kbdp->req_size)
|
if (kbdp->req_size)
|
||||||
{
|
{
|
||||||
@ -221,7 +226,9 @@ message *m;
|
|||||||
/* Should record proc */
|
/* Should record proc */
|
||||||
kbdp->req_size= m->COUNT;
|
kbdp->req_size= m->COUNT;
|
||||||
kbdp->req_proc= m->IO_ENDPT;
|
kbdp->req_proc= m->IO_ENDPT;
|
||||||
kbdp->req_addr= (vir_bytes)m->ADDRESS;
|
kbdp->req_addr_g= (vir_bytes)m->ADDRESS;
|
||||||
|
kbdp->req_addr_offset= 0;
|
||||||
|
kbdp->req_safe= safecopy;
|
||||||
kbdp->incaller= m->m_source;
|
kbdp->incaller= m->m_source;
|
||||||
r= SUSPEND;
|
r= SUSPEND;
|
||||||
break;
|
break;
|
||||||
@ -235,17 +242,27 @@ message *m;
|
|||||||
n= KBD_BUFSZ-kbdp->offset;
|
n= KBD_BUFSZ-kbdp->offset;
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
panic("TTY", "do_kbd(READ): bad n", n);
|
panic("TTY", "do_kbd(READ): bad n", n);
|
||||||
r= sys_vircopy(SELF, D, (vir_bytes)&kbdp->buf[kbdp->offset],
|
if(safecopy) {
|
||||||
|
r= sys_safecopyto(m->IO_ENDPT, (vir_bytes) m->ADDRESS, 0,
|
||||||
|
(vir_bytes) &kbdp->buf[kbdp->offset], n, D);
|
||||||
|
} else {
|
||||||
|
r= sys_vircopy(SELF, D, (vir_bytes)&kbdp->buf[kbdp->offset],
|
||||||
m->IO_ENDPT, D, (vir_bytes) m->ADDRESS, n);
|
m->IO_ENDPT, D, (vir_bytes) m->ADDRESS, n);
|
||||||
|
}
|
||||||
if (r == OK)
|
if (r == OK)
|
||||||
{
|
{
|
||||||
kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
|
kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
|
||||||
kbdp->avail -= n;
|
kbdp->avail -= n;
|
||||||
r= n;
|
r= n;
|
||||||
|
} else {
|
||||||
|
printf("copy in read kbd failed: %d\n", r);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DEV_WRITE_S:
|
||||||
|
safecopy = 1;
|
||||||
|
/* Fallthrough. */
|
||||||
case DEV_WRITE:
|
case DEV_WRITE:
|
||||||
if (kbdp != &kbdaux)
|
if (kbdp != &kbdaux)
|
||||||
{
|
{
|
||||||
@ -260,8 +277,14 @@ message *m;
|
|||||||
*/
|
*/
|
||||||
for (i= 0; i<m->COUNT; i++)
|
for (i= 0; i<m->COUNT; i++)
|
||||||
{
|
{
|
||||||
r= sys_vircopy(m->IO_ENDPT, D, (vir_bytes) m->ADDRESS+i,
|
if(safecopy) {
|
||||||
|
r= sys_safecopyfrom(m->IO_ENDPT, (vir_bytes)
|
||||||
|
m->ADDRESS, i, (vir_bytes)&c, 1, D);
|
||||||
|
} else {
|
||||||
|
r= sys_vircopy(m->IO_ENDPT, D,
|
||||||
|
(vir_bytes) m->ADDRESS+i,
|
||||||
SELF, D, (vir_bytes)&c, 1);
|
SELF, D, (vir_bytes)&c, 1);
|
||||||
|
}
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
break;
|
break;
|
||||||
kbc_cmd1(KBC_WRITE_AUX, c);
|
kbc_cmd1(KBC_WRITE_AUX, c);
|
||||||
@ -290,14 +313,24 @@ message *m;
|
|||||||
kbdp->select_proc= m->m_source;
|
kbdp->select_proc= m->m_source;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DEV_IOCTL_S:
|
||||||
|
safecopy=1;
|
||||||
|
/* Fallthrough. */
|
||||||
case DEV_IOCTL:
|
case DEV_IOCTL:
|
||||||
if (kbdp == &kbd && m->TTY_REQUEST == KIOCSLEDS)
|
if (kbdp == &kbd && m->TTY_REQUEST == KIOCSLEDS)
|
||||||
{
|
{
|
||||||
kio_leds_t leds;
|
kio_leds_t leds;
|
||||||
unsigned char b;
|
unsigned char b;
|
||||||
|
|
||||||
r= sys_vircopy(m->IO_ENDPT, D, (vir_bytes) m->ADDRESS,
|
|
||||||
|
if(safecopy) {
|
||||||
|
r= sys_safecopyfrom(m->IO_ENDPT, (vir_bytes)
|
||||||
|
m->ADDRESS, 0, (vir_bytes)&leds,
|
||||||
|
sizeof(leds), D);
|
||||||
|
} else {
|
||||||
|
r= sys_vircopy(m->IO_ENDPT, D, (vir_bytes) m->ADDRESS,
|
||||||
SELF, D, (vir_bytes)&leds, sizeof(leds));
|
SELF, D, (vir_bytes)&leds, sizeof(leds));
|
||||||
|
}
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
break;
|
break;
|
||||||
b= 0;
|
b= 0;
|
||||||
@ -330,8 +363,14 @@ message *m;
|
|||||||
kio_bell_t bell;
|
kio_bell_t bell;
|
||||||
clock_t ticks;
|
clock_t ticks;
|
||||||
|
|
||||||
r= sys_vircopy(m->IO_ENDPT, D, (vir_bytes) m->ADDRESS,
|
if(safecopy) {
|
||||||
|
r= sys_safecopyfrom(m->IO_ENDPT, (vir_bytes)
|
||||||
|
m->ADDRESS, 0, (vir_bytes)&bell,
|
||||||
|
sizeof(bell), D);
|
||||||
|
} else {
|
||||||
|
r= sys_vircopy(m->IO_ENDPT, D, (vir_bytes) m->ADDRESS,
|
||||||
SELF, D, (vir_bytes)&bell, sizeof(bell));
|
SELF, D, (vir_bytes)&bell, sizeof(bell));
|
||||||
|
}
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -376,17 +415,23 @@ message *m;
|
|||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
panic("TTY", "kbd_status: bad n", n);
|
panic("TTY", "kbd_status: bad n", n);
|
||||||
kbdp->req_size= 0;
|
kbdp->req_size= 0;
|
||||||
r= sys_vircopy(SELF, D, (vir_bytes)&kbdp->buf[kbdp->offset],
|
if(kbdp->req_safe) {
|
||||||
kbdp->req_proc, D, kbdp->req_addr, n);
|
r= sys_safecopyto(kbdp->req_proc, kbdp->req_addr_g, 0,
|
||||||
|
(vir_bytes)&kbdp->buf[kbdp->offset], n, D);
|
||||||
|
} else {
|
||||||
|
r= sys_vircopy(SELF, D, (vir_bytes)&kbdp->buf[kbdp->offset],
|
||||||
|
kbdp->req_proc, D, kbdp->req_addr_g, n);
|
||||||
|
}
|
||||||
if (r == OK)
|
if (r == OK)
|
||||||
{
|
{
|
||||||
kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
|
kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
|
||||||
kbdp->avail -= n;
|
kbdp->avail -= n;
|
||||||
r= n;
|
r= n;
|
||||||
}
|
} else printf("copy in revive kbd failed: %d\n", r);
|
||||||
|
|
||||||
m->m_type = DEV_REVIVE;
|
m->m_type = DEV_REVIVE;
|
||||||
m->REP_ENDPT= kbdp->req_proc;
|
m->REP_ENDPT= kbdp->req_proc;
|
||||||
|
m->REP_IO_GRANT= kbdp->req_addr_g;
|
||||||
m->REP_STATUS= r;
|
m->REP_STATUS= r;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -472,15 +517,18 @@ message *m_ptr;
|
|||||||
/* raw scan codes or aux data */
|
/* raw scan codes or aux data */
|
||||||
if (kbdp->avail >= KBD_BUFSZ)
|
if (kbdp->avail >= KBD_BUFSZ)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
printf("kbd_interrupt: %s buffer is full\n",
|
printf("kbd_interrupt: %s buffer is full\n",
|
||||||
isaux ? "kbdaux" : "keyboard");
|
isaux ? "kbdaux" : "keyboard");
|
||||||
|
#endif
|
||||||
return; /* Buffer is full */
|
return; /* Buffer is full */
|
||||||
}
|
}
|
||||||
o= (kbdp->offset + kbdp->avail) % KBD_BUFSZ;
|
o= (kbdp->offset + kbdp->avail) % KBD_BUFSZ;
|
||||||
kbdp->buf[o]= scode;
|
kbdp->buf[o]= scode;
|
||||||
kbdp->avail++;
|
kbdp->avail++;
|
||||||
if (kbdp->req_size)
|
if (kbdp->req_size) {
|
||||||
notify(kbdp->incaller);
|
notify(kbdp->incaller);
|
||||||
|
}
|
||||||
if (kbdp->select_ops & SEL_RD)
|
if (kbdp->select_ops & SEL_RD)
|
||||||
notify(kbdp->select_proc);
|
notify(kbdp->select_proc);
|
||||||
return;
|
return;
|
||||||
@ -583,14 +631,18 @@ PRIVATE void kbd_send()
|
|||||||
if (kbdout.expect_ack)
|
if (kbdout.expect_ack)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sys_inb(KB_STATUS, &sb);
|
if((r=sys_inb(KB_STATUS, &sb)) != OK) {
|
||||||
|
printf("kbd_send: 1 sys_inb() failed: %d\n", r);
|
||||||
|
}
|
||||||
if (sb & (KB_OUT_FULL|KB_IN_FULL))
|
if (sb & (KB_OUT_FULL|KB_IN_FULL))
|
||||||
{
|
{
|
||||||
printf("not sending 1: sb = 0x%x\n", sb);
|
printf("not sending 1: sb = 0x%x\n", sb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
micro_delay(KBC_IN_DELAY);
|
micro_delay(KBC_IN_DELAY);
|
||||||
sys_inb(KB_STATUS, &sb);
|
if((r=sys_inb(KB_STATUS, &sb)) != OK) {
|
||||||
|
printf("kbd_send: 2 sys_inb() failed: %d\n", r);
|
||||||
|
}
|
||||||
if (sb & (KB_OUT_FULL|KB_IN_FULL))
|
if (sb & (KB_OUT_FULL|KB_IN_FULL))
|
||||||
{
|
{
|
||||||
printf("not sending 2: sb = 0x%x\n", sb);
|
printf("not sending 2: sb = 0x%x\n", sb);
|
||||||
@ -601,7 +653,9 @@ PRIVATE void kbd_send()
|
|||||||
#if 0
|
#if 0
|
||||||
printf("sending byte 0x%x to keyboard\n", kbdout.buf[kbdout.offset]);
|
printf("sending byte 0x%x to keyboard\n", kbdout.buf[kbdout.offset]);
|
||||||
#endif
|
#endif
|
||||||
sys_outb(KEYBD, kbdout.buf[kbdout.offset]);
|
if((r=sys_outb(KEYBD, kbdout.buf[kbdout.offset])) != OK) {
|
||||||
|
printf("kbd_send: 3 sys_inb() failed: %d\n", r);
|
||||||
|
}
|
||||||
kbdout.offset++;
|
kbdout.offset++;
|
||||||
kbdout.avail--;
|
kbdout.avail--;
|
||||||
kbdout.expect_ack= 1;
|
kbdout.expect_ack= 1;
|
||||||
@ -734,7 +788,8 @@ PRIVATE void kbc_cmd0(cmd)
|
|||||||
int cmd;
|
int cmd;
|
||||||
{
|
{
|
||||||
kb_wait();
|
kb_wait();
|
||||||
sys_outb(KB_COMMAND, cmd);
|
if(sys_outb(KB_COMMAND, cmd) != OK)
|
||||||
|
printf("kbc_cmd0: sys_outb failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
@ -745,9 +800,11 @@ int cmd;
|
|||||||
int data;
|
int data;
|
||||||
{
|
{
|
||||||
kb_wait();
|
kb_wait();
|
||||||
sys_outb(KB_COMMAND, cmd);
|
if(sys_outb(KB_COMMAND, cmd) != OK)
|
||||||
|
printf("kbc_cmd1: 1 sys_outb failed\n");
|
||||||
kb_wait();
|
kb_wait();
|
||||||
sys_outb(KEYBD, data);
|
if(sys_outb(KEYBD, data) != OK)
|
||||||
|
printf("kbc_cmd1: 2 sys_outb failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -775,11 +832,13 @@ PRIVATE int kbc_read()
|
|||||||
do
|
do
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
sys_inb(KB_STATUS, &st);
|
if(sys_inb(KB_STATUS, &st) != OK)
|
||||||
|
printf("kbc_read: 1 sys_inb failed\n");
|
||||||
if (st & KB_OUT_FULL)
|
if (st & KB_OUT_FULL)
|
||||||
{
|
{
|
||||||
micro_delay(KBC_IN_DELAY);
|
micro_delay(KBC_IN_DELAY);
|
||||||
sys_inb(KEYBD, &byte);
|
if(sys_inb(KEYBD, &byte) != OK)
|
||||||
|
printf("kbc_read: 2 sys_inb failed\n");
|
||||||
if (st & KB_AUX_BYTE)
|
if (st & KB_AUX_BYTE)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -819,6 +878,8 @@ PRIVATE int kb_wait()
|
|||||||
retries = MAX_KB_BUSY_RETRIES + 1; /* wait until not busy */
|
retries = MAX_KB_BUSY_RETRIES + 1; /* wait until not busy */
|
||||||
do {
|
do {
|
||||||
s = sys_inb(KB_STATUS, &status);
|
s = sys_inb(KB_STATUS, &status);
|
||||||
|
if(s != OK)
|
||||||
|
printf("kb_wait: sys_inb failed: %d\n", s);
|
||||||
if (status & KB_OUT_FULL) {
|
if (status & KB_OUT_FULL) {
|
||||||
if (scan_keyboard(&byte, &isaux))
|
if (scan_keyboard(&byte, &isaux))
|
||||||
{
|
{
|
||||||
@ -847,6 +908,8 @@ PRIVATE int kb_ack()
|
|||||||
retries = MAX_KB_ACK_RETRIES + 1;
|
retries = MAX_KB_ACK_RETRIES + 1;
|
||||||
do {
|
do {
|
||||||
s = sys_inb(KEYBD, &u8val);
|
s = sys_inb(KEYBD, &u8val);
|
||||||
|
if(s != OK)
|
||||||
|
printf("kb_ack: sys_inb failed: %d\n", s);
|
||||||
if (u8val == KB_ACK)
|
if (u8val == KB_ACK)
|
||||||
break; /* wait for ack */
|
break; /* wait for ack */
|
||||||
} while(--retries != 0); /* continue unless timeout */
|
} while(--retries != 0); /* continue unless timeout */
|
||||||
@ -925,14 +988,20 @@ PUBLIC void kb_init_once(void)
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* kbd_loadmap *
|
* kbd_loadmap *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int kbd_loadmap(m)
|
PUBLIC int kbd_loadmap(m, safe)
|
||||||
message *m;
|
message *m;
|
||||||
|
int safe;
|
||||||
{
|
{
|
||||||
/* Load a new keymap. */
|
/* Load a new keymap. */
|
||||||
int result;
|
int result;
|
||||||
result = sys_vircopy(m->IO_ENDPT, D, (vir_bytes) m->ADDRESS,
|
if(safe) {
|
||||||
|
result = sys_safecopyfrom(m->IO_ENDPT, (vir_bytes) m->ADDRESS,
|
||||||
|
0, (vir_bytes) keymap, (vir_bytes) sizeof(keymap), D);
|
||||||
|
} else {
|
||||||
|
result = sys_vircopy(m->IO_ENDPT, D, (vir_bytes) m->ADDRESS,
|
||||||
SELF, D, (vir_bytes) keymap,
|
SELF, D, (vir_bytes) keymap,
|
||||||
(vir_bytes) sizeof(keymap));
|
(vir_bytes) sizeof(keymap));
|
||||||
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1137,30 +1206,35 @@ int *isauxp;
|
|||||||
|
|
||||||
byte_in[0].port = KEYBD; /* get the scan code for the key struck */
|
byte_in[0].port = KEYBD; /* get the scan code for the key struck */
|
||||||
byte_in[1].port = PORT_B; /* strobe the keyboard to ack the char */
|
byte_in[1].port = PORT_B; /* strobe the keyboard to ack the char */
|
||||||
sys_vinb(byte_in, 2); /* request actual input */
|
if(sys_vinb(byte_in, 2) != OK) /* request actual input */
|
||||||
|
printf("scan_keyboard: sys_vinb failed\n");
|
||||||
|
|
||||||
pv_set(byte_out[0], PORT_B, byte_in[1].value | KBIT); /* strobe bit high */
|
pv_set(byte_out[0], PORT_B, byte_in[1].value | KBIT); /* strobe bit high */
|
||||||
pv_set(byte_out[1], PORT_B, byte_in[1].value); /* then strobe low */
|
pv_set(byte_out[1], PORT_B, byte_in[1].value); /* then strobe low */
|
||||||
sys_voutb(byte_out, 2); /* request actual output */
|
if(sys_voutb(byte_out, 2) != OK) /* request actual output */
|
||||||
|
printf("scan_keyboard: sys_voutb failed\n");
|
||||||
|
|
||||||
return(byte_in[0].value); /* return scan code */
|
return(byte_in[0].value); /* return scan code */
|
||||||
#else
|
#else
|
||||||
unsigned long b, sb;
|
unsigned long b, sb;
|
||||||
|
|
||||||
sys_inb(KB_STATUS, &sb);
|
if(sys_inb(KB_STATUS, &sb) != OK)
|
||||||
|
printf("scan_keyboard: sys_inb failed\n");
|
||||||
|
|
||||||
if (!(sb & KB_OUT_FULL))
|
if (!(sb & KB_OUT_FULL))
|
||||||
{
|
{
|
||||||
if (kbdout.avail && !kbdout.expect_ack)
|
if (kbdout.avail && !kbdout.expect_ack)
|
||||||
kbd_send();
|
kbd_send();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
sys_inb(KEYBD, &b);
|
if(sys_inb(KEYBD, &b) != OK)
|
||||||
|
printf("scan_keyboard: 2 sys_inb failed\n");
|
||||||
#if 0
|
#if 0
|
||||||
printf("got byte 0x%x from %s\n", b, (sb & KB_AUX_BYTE) ? "AUX" : "keyboard");
|
printf("got byte 0x%x from %s\n", b, (sb & KB_AUX_BYTE) ? "AUX" : "keyboard");
|
||||||
#endif
|
#endif
|
||||||
if (!(sb & KB_AUX_BYTE) && b == KB_ACK && kbdout.expect_ack)
|
if (!(sb & KB_AUX_BYTE) && b == KB_ACK && kbdout.expect_ack)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 0
|
||||||
printf("got ACK from keyboard\n");
|
printf("got ACK from keyboard\n");
|
||||||
#endif
|
#endif
|
||||||
kbdout.expect_ack= 0;
|
kbdout.expect_ack= 0;
|
||||||
|
|||||||
@ -36,7 +36,9 @@ typedef struct pty {
|
|||||||
char rdsendreply; /* send a reply (instead of notify) */
|
char rdsendreply; /* send a reply (instead of notify) */
|
||||||
int rdcaller; /* process making the call (usually FS) */
|
int rdcaller; /* process making the call (usually FS) */
|
||||||
int rdproc; /* process that wants to read from the pty */
|
int rdproc; /* process that wants to read from the pty */
|
||||||
vir_bytes rdvir; /* virtual address in readers address space */
|
vir_bytes rdvir_g; /* virtual address in readers address space */
|
||||||
|
vir_bytes rdvir_offset; /* offset in above grant */
|
||||||
|
int rdsafe; /* safe read mode? */
|
||||||
int rdleft; /* # bytes yet to be read */
|
int rdleft; /* # bytes yet to be read */
|
||||||
int rdcum; /* # bytes written so far */
|
int rdcum; /* # bytes written so far */
|
||||||
|
|
||||||
@ -44,14 +46,16 @@ typedef struct pty {
|
|||||||
char wrsendreply; /* send a reply (instead of notify) */
|
char wrsendreply; /* send a reply (instead of notify) */
|
||||||
int wrcaller; /* process making the call (usually FS) */
|
int wrcaller; /* process making the call (usually FS) */
|
||||||
int wrproc; /* process that wants to write to the pty */
|
int wrproc; /* process that wants to write to the pty */
|
||||||
vir_bytes wrvir; /* virtual address in writers address space */
|
vir_bytes wrvir_g; /* virtual address in writers address space */
|
||||||
|
vir_bytes wrvir_offset; /* offset in above grant */
|
||||||
|
int wrsafe; /* safe write mode? */
|
||||||
int wrleft; /* # bytes yet to be written */
|
int wrleft; /* # bytes yet to be written */
|
||||||
int wrcum; /* # bytes written so far */
|
int wrcum; /* # bytes written so far */
|
||||||
|
|
||||||
/* Output buffer. */
|
/* Output buffer. */
|
||||||
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[2048]; /* buffer for bytes going to the pty reader */
|
||||||
|
|
||||||
/* select() data. */
|
/* select() data. */
|
||||||
int select_ops, /* Which operations do we want to know about? */
|
int select_ops, /* Which operations do we want to know about? */
|
||||||
@ -86,8 +90,12 @@ message *m_ptr;
|
|||||||
pty_t *pp = tp->tty_priv;
|
pty_t *pp = tp->tty_priv;
|
||||||
int r;
|
int r;
|
||||||
phys_bytes p;
|
phys_bytes p;
|
||||||
|
int safe = 0;
|
||||||
|
|
||||||
switch (m_ptr->m_type) {
|
switch (m_ptr->m_type) {
|
||||||
|
case DEV_READ_S:
|
||||||
|
safe=1;
|
||||||
|
/* fallthrough */
|
||||||
case DEV_READ:
|
case DEV_READ:
|
||||||
/* Check, store information on the reader, do I/O. */
|
/* Check, store information on the reader, do I/O. */
|
||||||
if (pp->state & TTY_CLOSED) {
|
if (pp->state & TTY_CLOSED) {
|
||||||
@ -114,21 +122,31 @@ message *m_ptr;
|
|||||||
pp->rdsendreply = TRUE;
|
pp->rdsendreply = TRUE;
|
||||||
pp->rdcaller = m_ptr->m_source;
|
pp->rdcaller = m_ptr->m_source;
|
||||||
pp->rdproc = m_ptr->IO_ENDPT;
|
pp->rdproc = m_ptr->IO_ENDPT;
|
||||||
pp->rdvir = (vir_bytes) m_ptr->ADDRESS;
|
pp->rdvir_g = (vir_bytes) m_ptr->ADDRESS;
|
||||||
|
pp->rdvir_offset = 0;
|
||||||
|
pp->rdsafe = safe;
|
||||||
pp->rdleft = m_ptr->COUNT;
|
pp->rdleft = m_ptr->COUNT;
|
||||||
pty_start(pp);
|
pty_start(pp);
|
||||||
handle_events(tp);
|
handle_events(tp);
|
||||||
if (pp->rdleft == 0) return; /* already done */
|
if (pp->rdleft == 0) {
|
||||||
|
return; /* already done */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEAD_CODE
|
||||||
if (m_ptr->TTY_FLAGS & O_NONBLOCK) {
|
if (m_ptr->TTY_FLAGS & O_NONBLOCK) {
|
||||||
r = EAGAIN; /* don't suspend */
|
r = EAGAIN; /* don't suspend */
|
||||||
pp->rdleft = pp->rdcum = 0;
|
pp->rdleft = pp->rdcum = 0;
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
r = SUSPEND; /* do suspend */
|
r = SUSPEND; /* do suspend */
|
||||||
pp->rdsendreply = FALSE;
|
pp->rdsendreply = FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DEV_WRITE_S:
|
||||||
|
safe=1;
|
||||||
|
/* fallthrough */
|
||||||
case DEV_WRITE:
|
case DEV_WRITE:
|
||||||
/* Check, store information on the writer, do I/O. */
|
/* Check, store information on the writer, do I/O. */
|
||||||
if (pp->state & TTY_CLOSED) {
|
if (pp->state & TTY_CLOSED) {
|
||||||
@ -156,15 +174,22 @@ message *m_ptr;
|
|||||||
pp->wrsendreply = TRUE;
|
pp->wrsendreply = TRUE;
|
||||||
pp->wrcaller = m_ptr->m_source;
|
pp->wrcaller = m_ptr->m_source;
|
||||||
pp->wrproc = m_ptr->IO_ENDPT;
|
pp->wrproc = m_ptr->IO_ENDPT;
|
||||||
pp->wrvir = (vir_bytes) m_ptr->ADDRESS;
|
pp->wrvir_g = (vir_bytes) m_ptr->ADDRESS;
|
||||||
|
pp->wrvir_offset = 0;
|
||||||
|
pp->wrsafe = safe;
|
||||||
pp->wrleft = m_ptr->COUNT;
|
pp->wrleft = m_ptr->COUNT;
|
||||||
handle_events(tp);
|
handle_events(tp);
|
||||||
if (pp->wrleft == 0) return; /* already done */
|
if (pp->wrleft == 0) {
|
||||||
|
return; /* already done */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEAD_CODE
|
||||||
if (m_ptr->TTY_FLAGS & O_NONBLOCK) { /* don't suspend */
|
if (m_ptr->TTY_FLAGS & O_NONBLOCK) { /* don't suspend */
|
||||||
r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
|
r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
|
||||||
pp->wrleft = pp->wrcum = 0;
|
pp->wrleft = pp->wrcum = 0;
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
pp->wrsendreply = FALSE; /* do suspend */
|
pp->wrsendreply = FALSE; /* do suspend */
|
||||||
r = SUSPEND;
|
r = SUSPEND;
|
||||||
}
|
}
|
||||||
@ -192,15 +217,17 @@ message *m_ptr;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CANCEL:
|
case CANCEL:
|
||||||
|
r = EINTR;
|
||||||
if (m_ptr->IO_ENDPT == pp->rdproc) {
|
if (m_ptr->IO_ENDPT == pp->rdproc) {
|
||||||
/* Cancel a read from a PTY. */
|
/* Cancel a read from a PTY. */
|
||||||
|
r = pp->rdcum > 0 ? pp->rdcum : EAGAIN;
|
||||||
pp->rdleft = pp->rdcum = 0;
|
pp->rdleft = pp->rdcum = 0;
|
||||||
}
|
}
|
||||||
if (m_ptr->IO_ENDPT == pp->wrproc) {
|
if (m_ptr->IO_ENDPT == pp->wrproc) {
|
||||||
/* Cancel a write to a PTY. */
|
/* Cancel a write to a PTY. */
|
||||||
|
r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
|
||||||
pp->wrleft = pp->wrcum = 0;
|
pp->wrleft = pp->wrcum = 0;
|
||||||
}
|
}
|
||||||
r = EINTR;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -227,9 +254,14 @@ int try;
|
|||||||
if (pp->state & PTY_CLOSED) {
|
if (pp->state & PTY_CLOSED) {
|
||||||
if (try) return 1;
|
if (try) return 1;
|
||||||
if (tp->tty_outleft > 0) {
|
if (tp->tty_outleft > 0) {
|
||||||
tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
|
if(tp->tty_outrepcode == TTY_REVIVE) {
|
||||||
|
notify(tp->tty_outcaller);
|
||||||
|
tp->tty_outrevived = 1;
|
||||||
|
} else {
|
||||||
|
tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
|
||||||
tp->tty_outproc, EIO);
|
tp->tty_outproc, EIO);
|
||||||
tp->tty_outleft = tp->tty_outcum = 0;
|
tp->tty_outleft = tp->tty_outcum = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -245,10 +277,16 @@ int try;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* 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(tp->tty_out_safe) {
|
||||||
SELF, D, (vir_bytes) pp->ohead, (phys_bytes) count)) != OK) {
|
if ((s = sys_safecopyfrom(tp->tty_outproc, tp->tty_out_vir_g,
|
||||||
printf("pty tty%d: copy failed (error %d)\n", s);
|
tp->tty_out_vir_offset, (vir_bytes) pp->ohead, count, D))!=OK) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((s = sys_vircopy(tp->tty_outproc, D, (vir_bytes) tp->tty_out_vir_g,
|
||||||
|
SELF, D, (vir_bytes) pp->ohead, (phys_bytes) count)) != OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform output processing on the output buffer. */
|
/* Perform output processing on the output buffer. */
|
||||||
@ -263,13 +301,21 @@ int try;
|
|||||||
if ((pp->ohead += ocount) >= bufend(pp->obuf))
|
if ((pp->ohead += ocount) >= bufend(pp->obuf))
|
||||||
pp->ohead -= buflen(pp->obuf);
|
pp->ohead -= buflen(pp->obuf);
|
||||||
pty_start(pp);
|
pty_start(pp);
|
||||||
tp->tty_out_vir += count;
|
|
||||||
|
if(tp->tty_out_safe) tp->tty_out_vir_offset += count;
|
||||||
|
else tp->tty_out_vir_g += count;
|
||||||
|
|
||||||
tp->tty_outcum += count;
|
tp->tty_outcum += count;
|
||||||
if ((tp->tty_outleft -= count) == 0) {
|
if ((tp->tty_outleft -= count) == 0) {
|
||||||
/* Output is finished, reply to the writer. */
|
/* Output is finished, reply to the writer. */
|
||||||
tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
|
if(tp->tty_outrepcode == TTY_REVIVE) {
|
||||||
|
notify(tp->tty_outcaller);
|
||||||
|
tp->tty_outrevived = 1;
|
||||||
|
} else {
|
||||||
|
tty_reply(tp->tty_outrepcode, tp->tty_outcaller,
|
||||||
tp->tty_outproc, tp->tty_outcum);
|
tp->tty_outproc, tp->tty_outcum);
|
||||||
tp->tty_outcum = 0;
|
tp->tty_outcum = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pty_finish(pp);
|
pty_finish(pp);
|
||||||
@ -319,16 +365,24 @@ pty_t *pp;
|
|||||||
if (count == 0) break;
|
if (count == 0) break;
|
||||||
|
|
||||||
/* Copy from the output buffer to the readers address space. */
|
/* Copy from the output buffer to the readers address space. */
|
||||||
if ((s = sys_vircopy(SELF, D, (vir_bytes)pp->otail,
|
if (pp->rdsafe) {
|
||||||
(vir_bytes) pp->rdproc, D, (vir_bytes) pp->rdvir, (phys_bytes) count)) != OK) {
|
if((s = sys_safecopyto(pp->rdproc, pp->rdvir_g,
|
||||||
printf("pty tty%d: copy failed (error %d)\n", s);
|
pp->rdvir_offset, (vir_bytes) pp->otail, count, D)) != OK) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
pp->rdvir_offset += count;
|
||||||
|
} else {
|
||||||
|
if ((s = sys_vircopy(SELF, D, (vir_bytes)pp->otail,
|
||||||
|
(vir_bytes) pp->rdproc, D, (vir_bytes) pp->rdvir_g, (phys_bytes) count)) != OK) {
|
||||||
|
printf("pty tty: copy failed (error %d)\n", s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pp->rdvir_g += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bookkeeping. */
|
/* Bookkeeping. */
|
||||||
pp->ocount -= count;
|
pp->ocount -= count;
|
||||||
if ((pp->otail += count) == bufend(pp->obuf)) pp->otail = pp->obuf;
|
if ((pp->otail += count) == bufend(pp->obuf)) pp->otail = pp->obuf;
|
||||||
pp->rdvir += count;
|
|
||||||
pp->rdcum += count;
|
pp->rdcum += count;
|
||||||
pp->rdleft -= count;
|
pp->rdleft -= count;
|
||||||
}
|
}
|
||||||
@ -370,9 +424,14 @@ int try;
|
|||||||
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) {
|
||||||
tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc,
|
if(tp->tty_inrepcode == TTY_REVIVE) {
|
||||||
tp->tty_incum);
|
notify(tp->tty_incaller);
|
||||||
tp->tty_inleft = tp->tty_incum = 0;
|
tp->tty_inrevived = 1;
|
||||||
|
} else {
|
||||||
|
tty_reply(tp->tty_inrepcode, tp->tty_incaller,
|
||||||
|
tp->tty_inproc, tp->tty_incum);
|
||||||
|
tp->tty_inleft = tp->tty_incum = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -387,17 +446,26 @@ int try;
|
|||||||
int s;
|
int s;
|
||||||
|
|
||||||
/* Transfer one character to 'c'. */
|
/* Transfer one character to 'c'. */
|
||||||
if ((s = sys_vircopy(pp->wrproc, D, (vir_bytes) pp->wrvir,
|
if(pp->wrsafe) {
|
||||||
|
if ((s = sys_safecopyfrom(pp->wrproc, pp->wrvir_g,
|
||||||
|
pp->wrvir_offset, (vir_bytes) &c, 1, D)) != OK) {
|
||||||
|
printf("pty: safecopy failed (error %d)\n", s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pp->wrvir_offset++;
|
||||||
|
} else {
|
||||||
|
if ((s = sys_vircopy(pp->wrproc, D, (vir_bytes) pp->wrvir_g,
|
||||||
SELF, D, (vir_bytes) &c, (phys_bytes) 1)) != OK) {
|
SELF, D, (vir_bytes) &c, (phys_bytes) 1)) != OK) {
|
||||||
printf("pty: copy failed (error %d)\n", s);
|
printf("pty: copy failed (error %d)\n", s);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
pp->wrvir_g++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input processing. */
|
/* Input processing. */
|
||||||
if (in_process(tp, &c, 1) == 0) break;
|
if (in_process(tp, &c, 1) == 0) break;
|
||||||
|
|
||||||
/* PTY writer bookkeeping. */
|
/* PTY writer bookkeeping. */
|
||||||
pp->wrvir++;
|
|
||||||
pp->wrcum++;
|
pp->wrcum++;
|
||||||
if (--pp->wrleft == 0) {
|
if (--pp->wrleft == 0) {
|
||||||
if (pp->wrsendreply) {
|
if (pp->wrsendreply) {
|
||||||
@ -447,7 +515,6 @@ int try;
|
|||||||
pty_t *pp = tp->tty_priv;
|
pty_t *pp = tp->tty_priv;
|
||||||
|
|
||||||
if (pp->wrleft > 0) {
|
if (pp->wrleft > 0) {
|
||||||
assert(!pp->wrsendreply);
|
|
||||||
pp->wrcum += pp->wrleft;
|
pp->wrcum += pp->wrleft;
|
||||||
pp->wrleft= 0;
|
pp->wrleft= 0;
|
||||||
notify(pp->wrcaller);
|
notify(pp->wrcaller);
|
||||||
@ -512,6 +579,7 @@ PUBLIC int pty_status(message *m_ptr)
|
|||||||
{
|
{
|
||||||
m_ptr->m_type = DEV_REVIVE;
|
m_ptr->m_type = DEV_REVIVE;
|
||||||
m_ptr->REP_ENDPT = pp->rdproc;
|
m_ptr->REP_ENDPT = pp->rdproc;
|
||||||
|
m_ptr->REP_IO_GRANT = pp->rdvir_g;
|
||||||
m_ptr->REP_STATUS = pp->rdcum;
|
m_ptr->REP_STATUS = pp->rdcum;
|
||||||
|
|
||||||
pp->rdleft = pp->rdcum = 0;
|
pp->rdleft = pp->rdcum = 0;
|
||||||
@ -525,6 +593,7 @@ PUBLIC int pty_status(message *m_ptr)
|
|||||||
{
|
{
|
||||||
m_ptr->m_type = DEV_REVIVE;
|
m_ptr->m_type = DEV_REVIVE;
|
||||||
m_ptr->REP_ENDPT = pp->wrproc;
|
m_ptr->REP_ENDPT = pp->wrproc;
|
||||||
|
m_ptr->REP_IO_GRANT = pp->wrvir_g;
|
||||||
if (pp->wrcum == 0)
|
if (pp->wrcum == 0)
|
||||||
m_ptr->REP_STATUS = EIO;
|
m_ptr->REP_STATUS = EIO;
|
||||||
else
|
else
|
||||||
|
|||||||
@ -321,8 +321,13 @@ int try;
|
|||||||
if (try) return 1;
|
if (try) return 1;
|
||||||
|
|
||||||
/* Copy from user space to the RS232 output buffer. */
|
/* Copy from user space to the RS232 output buffer. */
|
||||||
sys_vircopy(tp->tty_outproc, D, (vir_bytes) tp->tty_out_vir,
|
if(tp->tty_out_safe) {
|
||||||
|
sys_safecopyfrom(tp->tty_outproc, tp->tty_out_vir_g,
|
||||||
|
tp->tty_out_vir_offset, (vir_bytes) rs->ohead, count, D);
|
||||||
|
} else {
|
||||||
|
sys_vircopy(tp->tty_outproc, D, (vir_bytes) tp->tty_out_vir_g,
|
||||||
SELF, D, (vir_bytes) rs->ohead, (phys_bytes) count);
|
SELF, D, (vir_bytes) rs->ohead, (phys_bytes) count);
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform output processing on the output buffer. */
|
/* Perform output processing on the output buffer. */
|
||||||
out_process(tp, rs->obuf, rs->ohead, bufend(rs->obuf), &count, &ocount);
|
out_process(tp, rs->obuf, rs->ohead, bufend(rs->obuf), &count, &ocount);
|
||||||
@ -338,7 +343,11 @@ int try;
|
|||||||
unlock();
|
unlock();
|
||||||
if ((rs->ohead += ocount) >= bufend(rs->obuf))
|
if ((rs->ohead += ocount) >= bufend(rs->obuf))
|
||||||
rs->ohead -= buflen(rs->obuf);
|
rs->ohead -= buflen(rs->obuf);
|
||||||
tp->tty_out_vir += count;
|
if(tp->tty_out_safe) {
|
||||||
|
tp->tty_out_vir_offset += count;
|
||||||
|
} else {
|
||||||
|
tp->tty_out_vir_g += count;
|
||||||
|
}
|
||||||
tp->tty_outcum += count;
|
tp->tty_outcum += count;
|
||||||
if ((tp->tty_outleft -= count) == 0) {
|
if ((tp->tty_outleft -= count) == 0) {
|
||||||
/* Output is finished, reply to the writer. */
|
/* Output is finished, reply to the writer. */
|
||||||
|
|||||||
@ -29,26 +29,26 @@
|
|||||||
* DEV_STATUS: FS wants to know status for SELECT or REVIVE
|
* DEV_STATUS: FS wants to know status for SELECT or REVIVE
|
||||||
* CANCEL: terminate a previous incomplete system call immediately
|
* CANCEL: terminate a previous incomplete system call immediately
|
||||||
*
|
*
|
||||||
* m_type TTY_LINE IO_ENDPT COUNT TTY_SPEK TTY_FLAGS ADDRESS
|
* m_type TTY_LINE IO_ENDPT COUNT TTY_SPEKS ADDRESS
|
||||||
* ---------------------------------------------------------------------------
|
* -----------------------------------------------------------------
|
||||||
* | HARD_INT | | | | | | |
|
* | HARD_INT | | | | | |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | SYS_SIG | sig set | | | | | |
|
* | SYS_SIG | sig set | | | | |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | DEV_READ |minor dev| proc nr | count | O_NONBLOCK| buf ptr |
|
* | DEV_READ |minor dev| proc nr | count | | buf ptr |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | DEV_WRITE |minor dev| proc nr | count | | | buf ptr |
|
* | DEV_WRITE |minor dev| proc nr | count | | buf ptr |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | DEV_IOCTL |minor dev| proc nr |func code|erase etc| flags | |
|
* | DEV_IOCTL |minor dev| proc nr |func code|erase etc| |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | DEV_OPEN |minor dev| proc nr | O_NOCTTY| | | |
|
* | DEV_OPEN |minor dev| proc nr | O_NOCTTY| | |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | DEV_CLOSE |minor dev| proc nr | | | | |
|
* | DEV_CLOSE |minor dev| proc nr | | | |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | DEV_STATUS | | | | | | |
|
* | DEV_STATUS | | | | | |
|
||||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
* |-------------+---------+---------+---------+---------+---------|
|
||||||
* | CANCEL |minor dev| proc nr | | | | |
|
* | CANCEL |minor dev| proc nr | | | |
|
||||||
* ---------------------------------------------------------------------------
|
* -----------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Changes:
|
* Changes:
|
||||||
* Jan 20, 2004 moved TTY driver to user-space (Jorrit N. Herder)
|
* Jan 20, 2004 moved TTY driver to user-space (Jorrit N. Herder)
|
||||||
@ -58,9 +58,6 @@
|
|||||||
|
|
||||||
#include "../drivers.h"
|
#include "../drivers.h"
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT
|
|
||||||
#include <sgtty.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/ioc_tty.h>
|
#include <sys/ioc_tty.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <minix/callnr.h>
|
#include <minix/callnr.h>
|
||||||
@ -106,11 +103,11 @@ FORWARD _PROTOTYPE( void tty_timed_out, (timer_t *tp) );
|
|||||||
FORWARD _PROTOTYPE( void expire_timers, (void) );
|
FORWARD _PROTOTYPE( void expire_timers, (void) );
|
||||||
FORWARD _PROTOTYPE( void settimer, (tty_t *tty_ptr, int enable) );
|
FORWARD _PROTOTYPE( void settimer, (tty_t *tty_ptr, int enable) );
|
||||||
FORWARD _PROTOTYPE( void do_cancel, (tty_t *tp, message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_cancel, (tty_t *tp, message *m_ptr) );
|
||||||
FORWARD _PROTOTYPE( void do_ioctl, (tty_t *tp, message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_ioctl, (tty_t *tp, message *m_ptr, int s) );
|
||||||
FORWARD _PROTOTYPE( void do_open, (tty_t *tp, message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_open, (tty_t *tp, message *m_ptr) );
|
||||||
FORWARD _PROTOTYPE( void do_close, (tty_t *tp, message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_close, (tty_t *tp, message *m_ptr) );
|
||||||
FORWARD _PROTOTYPE( void do_read, (tty_t *tp, message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_read, (tty_t *tp, message *m_ptr, int s) );
|
||||||
FORWARD _PROTOTYPE( void do_write, (tty_t *tp, message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_write, (tty_t *tp, message *m_ptr, int s) );
|
||||||
FORWARD _PROTOTYPE( void do_select, (tty_t *tp, message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_select, (tty_t *tp, message *m_ptr) );
|
||||||
FORWARD _PROTOTYPE( void do_status, (message *m_ptr) );
|
FORWARD _PROTOTYPE( void do_status, (message *m_ptr) );
|
||||||
FORWARD _PROTOTYPE( void in_transfer, (tty_t *tp) );
|
FORWARD _PROTOTYPE( void in_transfer, (tty_t *tp) );
|
||||||
@ -122,17 +119,6 @@ FORWARD _PROTOTYPE( void dev_ioctl, (tty_t *tp) );
|
|||||||
FORWARD _PROTOTYPE( void setattr, (tty_t *tp) );
|
FORWARD _PROTOTYPE( void setattr, (tty_t *tp) );
|
||||||
FORWARD _PROTOTYPE( void tty_icancel, (tty_t *tp) );
|
FORWARD _PROTOTYPE( void tty_icancel, (tty_t *tp) );
|
||||||
FORWARD _PROTOTYPE( void tty_init, (void) );
|
FORWARD _PROTOTYPE( void tty_init, (void) );
|
||||||
#if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT
|
|
||||||
FORWARD _PROTOTYPE( int compat_getp, (tty_t *tp, struct sgttyb *sg) );
|
|
||||||
FORWARD _PROTOTYPE( int compat_getc, (tty_t *tp, struct tchars *sg) );
|
|
||||||
FORWARD _PROTOTYPE( int compat_setp, (tty_t *tp, struct sgttyb *sg) );
|
|
||||||
FORWARD _PROTOTYPE( int compat_setc, (tty_t *tp, struct tchars *sg) );
|
|
||||||
FORWARD _PROTOTYPE( int tspd2sgspd, (speed_t tspd) );
|
|
||||||
FORWARD _PROTOTYPE( speed_t sgspd2tspd, (int sgspd) );
|
|
||||||
#if ENABLE_BINCOMPAT
|
|
||||||
FORWARD _PROTOTYPE( void do_ioctl_compat, (tty_t *tp, message *m_ptr) );
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Default attributes. */
|
/* Default attributes. */
|
||||||
PRIVATE struct termios termios_defaults = {
|
PRIVATE struct termios termios_defaults = {
|
||||||
@ -165,17 +151,6 @@ PUBLIC void main(void)
|
|||||||
register struct proc *rp;
|
register struct proc *rp;
|
||||||
register tty_t *tp;
|
register tty_t *tp;
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
kputc('H');
|
|
||||||
kputc('e');
|
|
||||||
kputc('l');
|
|
||||||
kputc('l');
|
|
||||||
kputc('o');
|
|
||||||
kputc(',');
|
|
||||||
kputc(' ');
|
|
||||||
printf("TTY\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get kernel environment (protected_mode, pc_at and ega are needed). */
|
/* Get kernel environment (protected_mode, pc_at and ega are needed). */
|
||||||
if (OK != (s=sys_getmachine(&machine))) {
|
if (OK != (s=sys_getmachine(&machine))) {
|
||||||
panic("TTY","Couldn't obtain kernel environment.", s);
|
panic("TTY","Couldn't obtain kernel environment.", s);
|
||||||
@ -229,13 +204,6 @@ PUBLIC void main(void)
|
|||||||
}
|
}
|
||||||
case PROC_EVENT: {
|
case PROC_EVENT: {
|
||||||
cons_stop(); /* switch to primary console */
|
cons_stop(); /* switch to primary console */
|
||||||
printf("TTY got PROC_EVENT, assuming SIGTERM\n");
|
|
||||||
#if DEAD_CODE
|
|
||||||
if (irq_hook_id != -1) {
|
|
||||||
sys_irqdisable(&irq_hook_id);
|
|
||||||
sys_irqrmpolicy(KEYBOARD_IRQ, &irq_hook_id);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case SYS_SIG: { /* system signal */
|
case SYS_SIG: { /* system signal */
|
||||||
@ -244,7 +212,10 @@ PUBLIC void main(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case DIAGNOSTICS: /* a server wants to print some */
|
case DIAGNOSTICS: /* a server wants to print some */
|
||||||
do_diagnostics(&tty_mess);
|
do_diagnostics(&tty_mess, 0);
|
||||||
|
continue;
|
||||||
|
case DIAGNOSTICS_S:
|
||||||
|
do_diagnostics(&tty_mess, 1);
|
||||||
continue;
|
continue;
|
||||||
case GET_KMESS:
|
case GET_KMESS:
|
||||||
do_get_kmess(&tty_mess);
|
do_get_kmess(&tty_mess);
|
||||||
@ -284,7 +255,8 @@ PUBLIC void main(void)
|
|||||||
tp = tty_addr(line - TTYPX_MINOR + NR_CONS + NR_RS_LINES);
|
tp = tty_addr(line - TTYPX_MINOR + NR_CONS + NR_RS_LINES);
|
||||||
} else if ((line - PTYPX_MINOR) < NR_PTYS) {
|
} else if ((line - PTYPX_MINOR) < NR_PTYS) {
|
||||||
tp = tty_addr(line - PTYPX_MINOR + NR_CONS + NR_RS_LINES);
|
tp = tty_addr(line - PTYPX_MINOR + NR_CONS + NR_RS_LINES);
|
||||||
if (tty_mess.m_type != DEV_IOCTL) {
|
if (tty_mess.m_type != DEV_IOCTL &&
|
||||||
|
tty_mess.m_type != DEV_IOCTL_S) {
|
||||||
do_pty(tp, &tty_mess);
|
do_pty(tp, &tty_mess);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -306,9 +278,12 @@ PUBLIC void main(void)
|
|||||||
|
|
||||||
/* Execute the requested device driver function. */
|
/* Execute the requested device driver function. */
|
||||||
switch (tty_mess.m_type) {
|
switch (tty_mess.m_type) {
|
||||||
case DEV_READ: do_read(tp, &tty_mess); break;
|
case DEV_READ: do_read(tp, &tty_mess, 0); break;
|
||||||
case DEV_WRITE: do_write(tp, &tty_mess); break;
|
case DEV_READ_S: do_read(tp, &tty_mess, 1); break;
|
||||||
case DEV_IOCTL: do_ioctl(tp, &tty_mess); break;
|
case DEV_WRITE: do_write(tp, &tty_mess, 0); break;
|
||||||
|
case DEV_WRITE_S: do_write(tp, &tty_mess, 1); break;
|
||||||
|
case DEV_IOCTL: do_ioctl(tp, &tty_mess, 0); break;
|
||||||
|
case DEV_IOCTL_S: do_ioctl(tp, &tty_mess, 1); break;
|
||||||
case DEV_OPEN: do_open(tp, &tty_mess); break;
|
case DEV_OPEN: do_open(tp, &tty_mess); break;
|
||||||
case DEV_CLOSE: do_close(tp, &tty_mess); break;
|
case DEV_CLOSE: do_close(tp, &tty_mess); break;
|
||||||
case DEV_SELECT: do_select(tp, &tty_mess); break;
|
case DEV_SELECT: do_select(tp, &tty_mess); break;
|
||||||
@ -356,6 +331,7 @@ message *m_ptr;
|
|||||||
/* Suspended request finished. Send a REVIVE. */
|
/* Suspended request finished. Send a REVIVE. */
|
||||||
m_ptr->m_type = DEV_REVIVE;
|
m_ptr->m_type = DEV_REVIVE;
|
||||||
m_ptr->REP_ENDPT = tp->tty_inproc;
|
m_ptr->REP_ENDPT = tp->tty_inproc;
|
||||||
|
m_ptr->REP_IO_GRANT = tp->tty_in_vir_g;
|
||||||
m_ptr->REP_STATUS = tp->tty_incum;
|
m_ptr->REP_STATUS = tp->tty_incum;
|
||||||
|
|
||||||
tp->tty_inleft = tp->tty_incum = 0;
|
tp->tty_inleft = tp->tty_incum = 0;
|
||||||
@ -368,6 +344,7 @@ message *m_ptr;
|
|||||||
/* Suspended request finished. Send a REVIVE. */
|
/* Suspended request finished. Send a REVIVE. */
|
||||||
m_ptr->m_type = DEV_REVIVE;
|
m_ptr->m_type = DEV_REVIVE;
|
||||||
m_ptr->REP_ENDPT = tp->tty_outproc;
|
m_ptr->REP_ENDPT = tp->tty_outproc;
|
||||||
|
m_ptr->REP_IO_GRANT = tp->tty_out_vir_g;
|
||||||
m_ptr->REP_STATUS = tp->tty_outcum;
|
m_ptr->REP_STATUS = tp->tty_outcum;
|
||||||
|
|
||||||
tp->tty_outcum = 0;
|
tp->tty_outcum = 0;
|
||||||
@ -375,6 +352,16 @@ message *m_ptr;
|
|||||||
event_found = 1;
|
event_found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (tp->tty_iorevived && tp->tty_iocaller == m_ptr->m_source) {
|
||||||
|
/* Suspended request finished. Send a REVIVE. */
|
||||||
|
m_ptr->m_type = DEV_REVIVE;
|
||||||
|
m_ptr->REP_ENDPT = tp->tty_ioproc;
|
||||||
|
m_ptr->REP_IO_GRANT = tp->tty_iovir_g;
|
||||||
|
m_ptr->REP_STATUS = tp->tty_iostatus;
|
||||||
|
tp->tty_iorevived = 0; /* unmark revive event */
|
||||||
|
event_found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NR_PTYS > 0
|
#if NR_PTYS > 0
|
||||||
@ -398,36 +385,30 @@ message *m_ptr;
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_read *
|
* do_read *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE void do_read(tp, m_ptr)
|
PRIVATE void do_read(tp, m_ptr, safe)
|
||||||
register tty_t *tp; /* pointer to tty struct */
|
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 safe; /* use safecopies? */
|
||||||
{
|
{
|
||||||
/* A process wants to read from a terminal. */
|
/* A process wants to read from a terminal. */
|
||||||
int r, status;
|
int r, status;
|
||||||
phys_bytes phys_addr;
|
|
||||||
int more_verbose= (tp == tty_addr(NR_CONS));
|
|
||||||
|
|
||||||
/* Check if there is already a process hanging in a read, check if the
|
/* Check if there is already a process hanging in a read, check if the
|
||||||
* parameters are correct, do I/O.
|
* parameters are correct, do I/O.
|
||||||
*/
|
*/
|
||||||
if (tp->tty_inleft > 0) {
|
if (tp->tty_inleft > 0) {
|
||||||
if (more_verbose) printf("do_read: EIO\n");
|
|
||||||
r = EIO;
|
r = EIO;
|
||||||
} else
|
} else
|
||||||
if (m_ptr->COUNT <= 0) {
|
if (m_ptr->COUNT <= 0) {
|
||||||
if (more_verbose) printf("do_read: EINVAL\n");
|
|
||||||
r = EINVAL;
|
r = EINVAL;
|
||||||
} else
|
|
||||||
if (sys_umap(m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS, m_ptr->COUNT,
|
|
||||||
&phys_addr) != OK) {
|
|
||||||
if (more_verbose) printf("do_read: EFAULT\n");
|
|
||||||
r = EFAULT;
|
|
||||||
} else {
|
} else {
|
||||||
/* Copy information from the message to the tty struct. */
|
/* Copy information from the message to the tty struct. */
|
||||||
tp->tty_inrepcode = TASK_REPLY;
|
tp->tty_inrepcode = TASK_REPLY;
|
||||||
tp->tty_incaller = m_ptr->m_source;
|
tp->tty_incaller = m_ptr->m_source;
|
||||||
tp->tty_inproc = m_ptr->IO_ENDPT;
|
tp->tty_inproc = m_ptr->IO_ENDPT;
|
||||||
tp->tty_in_vir = (vir_bytes) m_ptr->ADDRESS;
|
tp->tty_in_vir_g = (vir_bytes) m_ptr->ADDRESS;
|
||||||
|
tp->tty_in_vir_offset = 0;
|
||||||
|
tp->tty_in_safe = safe;
|
||||||
tp->tty_inleft = m_ptr->COUNT;
|
tp->tty_inleft = m_ptr->COUNT;
|
||||||
|
|
||||||
if (!(tp->tty_termios.c_lflag & ICANON)
|
if (!(tp->tty_termios.c_lflag & ICANON)
|
||||||
@ -459,18 +440,12 @@ register message *m_ptr; /* pointer to message sent to the task */
|
|||||||
return; /* already done */
|
return; /* already done */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There were no bytes in the input queue available, so either suspend
|
/* There were no bytes in the input queue available, so suspend
|
||||||
* the caller or break off the read if nonblocking.
|
* the caller.
|
||||||
*/
|
*/
|
||||||
if (m_ptr->TTY_FLAGS & O_NONBLOCK) {
|
r = SUSPEND; /* suspend the caller */
|
||||||
r = EAGAIN; /* cancel the read */
|
tp->tty_inrepcode = TTY_REVIVE;
|
||||||
tp->tty_inleft = tp->tty_incum = 0;
|
|
||||||
} else {
|
|
||||||
r = SUSPEND; /* suspend the caller */
|
|
||||||
tp->tty_inrepcode = REVIVE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (more_verbose) printf("do_read: replying %d\n", r);
|
|
||||||
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->IO_ENDPT, r);
|
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->IO_ENDPT, r);
|
||||||
if (tp->tty_select_ops)
|
if (tp->tty_select_ops)
|
||||||
select_retry(tp);
|
select_retry(tp);
|
||||||
@ -479,13 +454,13 @@ register message *m_ptr; /* pointer to message sent to the task */
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_write *
|
* do_write *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE void do_write(tp, m_ptr)
|
PRIVATE void do_write(tp, m_ptr, safe)
|
||||||
register tty_t *tp;
|
register tty_t *tp;
|
||||||
register message *m_ptr; /* pointer to message sent to the task */
|
register message *m_ptr; /* pointer to message sent to the task */
|
||||||
|
int safe;
|
||||||
{
|
{
|
||||||
/* A process wants to write on a terminal. */
|
/* A process wants to write on a terminal. */
|
||||||
int r;
|
int r;
|
||||||
phys_bytes phys_addr;
|
|
||||||
|
|
||||||
/* Check if there is already a process hanging in a write, check if the
|
/* Check if there is already a process hanging in a write, check if the
|
||||||
* parameters are correct, do I/O.
|
* parameters are correct, do I/O.
|
||||||
@ -495,16 +470,14 @@ register message *m_ptr; /* pointer to message sent to the task */
|
|||||||
} else
|
} else
|
||||||
if (m_ptr->COUNT <= 0) {
|
if (m_ptr->COUNT <= 0) {
|
||||||
r = EINVAL;
|
r = EINVAL;
|
||||||
} else
|
|
||||||
if (sys_umap(m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS, m_ptr->COUNT,
|
|
||||||
&phys_addr) != OK) {
|
|
||||||
r = EFAULT;
|
|
||||||
} else {
|
} else {
|
||||||
/* Copy message parameters to the tty structure. */
|
/* Copy message parameters to the tty structure. */
|
||||||
tp->tty_outrepcode = TASK_REPLY;
|
tp->tty_outrepcode = TASK_REPLY;
|
||||||
tp->tty_outcaller = m_ptr->m_source;
|
tp->tty_outcaller = m_ptr->m_source;
|
||||||
tp->tty_outproc = m_ptr->IO_ENDPT;
|
tp->tty_outproc = m_ptr->IO_ENDPT;
|
||||||
tp->tty_out_vir = (vir_bytes) m_ptr->ADDRESS;
|
tp->tty_out_vir_g = (vir_bytes) m_ptr->ADDRESS;
|
||||||
|
tp->tty_out_vir_offset = 0;
|
||||||
|
tp->tty_out_safe = safe;
|
||||||
tp->tty_outleft = m_ptr->COUNT;
|
tp->tty_outleft = m_ptr->COUNT;
|
||||||
|
|
||||||
/* Try to write. */
|
/* Try to write. */
|
||||||
@ -512,16 +485,11 @@ register message *m_ptr; /* pointer to message sent to the task */
|
|||||||
if (tp->tty_outleft == 0)
|
if (tp->tty_outleft == 0)
|
||||||
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 suspend the
|
||||||
* caller or break off the write if nonblocking.
|
* caller.
|
||||||
*/
|
*/
|
||||||
if (m_ptr->TTY_FLAGS & O_NONBLOCK) { /* cancel the write */
|
r = SUSPEND; /* suspend the caller */
|
||||||
r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
|
tp->tty_outrepcode = TTY_REVIVE;
|
||||||
tp->tty_outleft = tp->tty_outcum = 0;
|
|
||||||
} else {
|
|
||||||
r = SUSPEND; /* suspend the caller */
|
|
||||||
tp->tty_outrepcode = REVIVE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->IO_ENDPT, r);
|
tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->IO_ENDPT, r);
|
||||||
}
|
}
|
||||||
@ -529,9 +497,10 @@ register message *m_ptr; /* pointer to message sent to the task */
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_ioctl *
|
* do_ioctl *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE void do_ioctl(tp, m_ptr)
|
PRIVATE void do_ioctl(tp, m_ptr, safe)
|
||||||
register tty_t *tp;
|
register tty_t *tp;
|
||||||
message *m_ptr; /* pointer to message sent to task */
|
message *m_ptr; /* pointer to message sent to task */
|
||||||
|
int safe;
|
||||||
{
|
{
|
||||||
/* Perform an IOCTL on this terminal. Posix termios calls are handled
|
/* Perform an IOCTL on this terminal. Posix termios calls are handled
|
||||||
* by the IOCTL system call
|
* by the IOCTL system call
|
||||||
@ -540,10 +509,6 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
int r;
|
int r;
|
||||||
union {
|
union {
|
||||||
int i;
|
int i;
|
||||||
#if ENABLE_SRCCOMPAT
|
|
||||||
struct sgttyb sg;
|
|
||||||
struct tchars tc;
|
|
||||||
#endif
|
|
||||||
} param;
|
} param;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
@ -569,17 +534,6 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
size = sizeof(struct winsize);
|
size = sizeof(struct winsize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if ENABLE_SRCCOMPAT
|
|
||||||
case TIOCGETP: /* BSD-style get terminal properties */
|
|
||||||
case TIOCSETP: /* BSD-style set terminal properties */
|
|
||||||
size = sizeof(struct sgttyb);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TIOCGETC: /* BSD-style get terminal special characters */
|
|
||||||
case TIOCSETC: /* BSD-style get terminal special characters */
|
|
||||||
size = sizeof(struct tchars);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if (MACHINE == IBM_PC)
|
#if (MACHINE == IBM_PC)
|
||||||
case KIOCSMAP: /* load keymap (Minix extension) */
|
case KIOCSMAP: /* load keymap (Minix extension) */
|
||||||
size = sizeof(keymap_t);
|
size = sizeof(keymap_t);
|
||||||
@ -598,9 +552,14 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
switch (m_ptr->TTY_REQUEST) {
|
switch (m_ptr->TTY_REQUEST) {
|
||||||
case TCGETS:
|
case TCGETS:
|
||||||
/* Get the termios attributes. */
|
/* Get the termios attributes. */
|
||||||
r = sys_vircopy(SELF, D, (vir_bytes) &tp->tty_termios,
|
if(safe) {
|
||||||
|
r = sys_safecopyto(m_ptr->IO_ENDPT, (vir_bytes) m_ptr->ADDRESS, 0,
|
||||||
|
(vir_bytes) &tp->tty_termios, (vir_bytes) size, D);
|
||||||
|
} else {
|
||||||
|
r = sys_vircopy(SELF, D, (vir_bytes) &tp->tty_termios,
|
||||||
m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
||||||
(vir_bytes) size);
|
(vir_bytes) size);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCSETSW:
|
case TCSETSW:
|
||||||
@ -611,7 +570,8 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
tp->tty_iocaller = m_ptr->m_source;
|
tp->tty_iocaller = m_ptr->m_source;
|
||||||
tp->tty_ioproc = m_ptr->IO_ENDPT;
|
tp->tty_ioproc = m_ptr->IO_ENDPT;
|
||||||
tp->tty_ioreq = m_ptr->REQUEST;
|
tp->tty_ioreq = m_ptr->REQUEST;
|
||||||
tp->tty_iovir = (vir_bytes) m_ptr->ADDRESS;
|
tp->tty_iovir_g = (vir_bytes) m_ptr->ADDRESS;
|
||||||
|
tp->tty_io_safe = safe;
|
||||||
r = SUSPEND;
|
r = SUSPEND;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -620,15 +580,25 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
/*FALL THROUGH*/
|
/*FALL THROUGH*/
|
||||||
case TCSETS:
|
case TCSETS:
|
||||||
/* Set the termios attributes. */
|
/* Set the termios attributes. */
|
||||||
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
if(safe) {
|
||||||
SELF, D, (vir_bytes) &tp->tty_termios, (vir_bytes) size);
|
r = sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes) m_ptr->ADDRESS, 0,
|
||||||
|
(vir_bytes) &tp->tty_termios, (vir_bytes) size, D);
|
||||||
|
} else {
|
||||||
|
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
||||||
|
SELF, D, (vir_bytes) &tp->tty_termios, (vir_bytes) size);
|
||||||
|
}
|
||||||
if (r != OK) break;
|
if (r != OK) break;
|
||||||
setattr(tp);
|
setattr(tp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCFLSH:
|
case TCFLSH:
|
||||||
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
if(safe) {
|
||||||
|
r = sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes) m_ptr->ADDRESS, 0,
|
||||||
|
(vir_bytes) ¶m.i, (vir_bytes) size, D);
|
||||||
|
} else {
|
||||||
|
r = sys_vircopy(m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
||||||
SELF, D, (vir_bytes) ¶m.i, (vir_bytes) size);
|
SELF, D, (vir_bytes) ¶m.i, (vir_bytes) size);
|
||||||
|
}
|
||||||
if (r != OK) break;
|
if (r != OK) break;
|
||||||
switch (param.i) {
|
switch (param.i) {
|
||||||
case TCIFLUSH: tty_icancel(tp); break;
|
case TCIFLUSH: tty_icancel(tp); break;
|
||||||
@ -639,8 +609,13 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TCFLOW:
|
case TCFLOW:
|
||||||
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
if(safe) {
|
||||||
|
r = sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes) m_ptr->ADDRESS, 0,
|
||||||
|
(vir_bytes) ¶m.i, (vir_bytes) size, D);
|
||||||
|
} else {
|
||||||
|
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
||||||
SELF, D, (vir_bytes) ¶m.i, (vir_bytes) size);
|
SELF, D, (vir_bytes) ¶m.i, (vir_bytes) size);
|
||||||
|
}
|
||||||
if (r != OK) break;
|
if (r != OK) break;
|
||||||
switch (param.i) {
|
switch (param.i) {
|
||||||
case TCOOFF:
|
case TCOOFF:
|
||||||
@ -664,51 +639,31 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TIOCGWINSZ:
|
case TIOCGWINSZ:
|
||||||
r = sys_vircopy(SELF, D, (vir_bytes) &tp->tty_winsize,
|
if(safe) {
|
||||||
|
r = sys_safecopyto(m_ptr->IO_ENDPT, (vir_bytes) m_ptr->ADDRESS, 0,
|
||||||
|
(vir_bytes) &tp->tty_winsize, (vir_bytes) size, D);
|
||||||
|
} else {
|
||||||
|
r = sys_vircopy(SELF, D, (vir_bytes) &tp->tty_winsize,
|
||||||
m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
||||||
(vir_bytes) size);
|
(vir_bytes) size);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIOCSWINSZ:
|
case TIOCSWINSZ:
|
||||||
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
if(safe) {
|
||||||
|
r = sys_safecopyfrom(m_ptr->IO_ENDPT, (vir_bytes) m_ptr->ADDRESS, 0,
|
||||||
|
(vir_bytes) &tp->tty_winsize, (vir_bytes) size, D);
|
||||||
|
} else {
|
||||||
|
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
||||||
SELF, D, (vir_bytes) &tp->tty_winsize, (vir_bytes) size);
|
SELF, D, (vir_bytes) &tp->tty_winsize, (vir_bytes) size);
|
||||||
|
}
|
||||||
sigchar(tp, SIGWINCH);
|
sigchar(tp, SIGWINCH);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if ENABLE_SRCCOMPAT
|
|
||||||
case TIOCGETP:
|
|
||||||
compat_getp(tp, ¶m.sg);
|
|
||||||
r = sys_vircopy(SELF, D, (vir_bytes) ¶m.sg,
|
|
||||||
m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
|
||||||
(vir_bytes) size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TIOCSETP:
|
|
||||||
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
|
||||||
SELF, D, (vir_bytes) ¶m.sg, (vir_bytes) size);
|
|
||||||
if (r != OK) break;
|
|
||||||
compat_setp(tp, ¶m.sg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TIOCGETC:
|
|
||||||
compat_getc(tp, ¶m.tc);
|
|
||||||
r = sys_vircopy(SELF, D, (vir_bytes) ¶m.tc,
|
|
||||||
m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
|
||||||
(vir_bytes) size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TIOCSETC:
|
|
||||||
r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
|
|
||||||
SELF, D, (vir_bytes) ¶m.tc, (vir_bytes) size);
|
|
||||||
if (r != OK) break;
|
|
||||||
compat_setc(tp, ¶m.tc);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MACHINE == IBM_PC)
|
#if (MACHINE == IBM_PC)
|
||||||
case KIOCSMAP:
|
case KIOCSMAP:
|
||||||
/* Load a new keymap (only /dev/console). */
|
/* Load a new keymap (only /dev/console). */
|
||||||
if (isconsole(tp)) r = kbd_loadmap(m_ptr);
|
if (isconsole(tp)) r = kbd_loadmap(m_ptr, safe);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIOCSFON:
|
case TIOCSFON:
|
||||||
@ -729,12 +684,7 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
case TIOCGPGRP:
|
case TIOCGPGRP:
|
||||||
case TIOCSPGRP:
|
case TIOCSPGRP:
|
||||||
default:
|
default:
|
||||||
#if ENABLE_BINCOMPAT
|
|
||||||
do_ioctl_compat(tp, m_ptr);
|
|
||||||
return;
|
|
||||||
#else
|
|
||||||
r = ENOTTY;
|
r = ENOTTY;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the reply. */
|
/* Send the reply. */
|
||||||
@ -801,26 +751,33 @@ message *m_ptr; /* pointer to message sent to task */
|
|||||||
|
|
||||||
int proc_nr;
|
int proc_nr;
|
||||||
int mode;
|
int mode;
|
||||||
|
int r = EINTR;
|
||||||
|
|
||||||
/* Check the parameters carefully, to avoid cancelling twice. */
|
/* Check the parameters carefully, to avoid cancelling twice. */
|
||||||
proc_nr = m_ptr->IO_ENDPT;
|
proc_nr = m_ptr->IO_ENDPT;
|
||||||
mode = m_ptr->COUNT;
|
mode = m_ptr->COUNT;
|
||||||
if ((mode & R_BIT) && tp->tty_inleft != 0 && proc_nr == tp->tty_inproc) {
|
if ((mode & R_BIT) && tp->tty_inleft != 0 && proc_nr == tp->tty_inproc &&
|
||||||
|
(!tp->tty_in_safe || tp->tty_in_vir_g==(vir_bytes)m_ptr->IO_GRANT)) {
|
||||||
/* Process was reading when killed. Clean up input. */
|
/* Process was reading when killed. Clean up input. */
|
||||||
tty_icancel(tp);
|
tty_icancel(tp);
|
||||||
tp->tty_inleft = tp->tty_incum = 0;
|
r = tp->tty_incum > 0 ? tp->tty_incum : EAGAIN;
|
||||||
}
|
tp->tty_inleft = tp->tty_incum = tp->tty_inrevived = 0;
|
||||||
if ((mode & W_BIT) && tp->tty_outleft != 0 && proc_nr == tp->tty_outproc) {
|
}
|
||||||
|
if ((mode & W_BIT) && tp->tty_outleft != 0 && proc_nr == tp->tty_outproc &&
|
||||||
|
(!tp->tty_out_safe || tp->tty_out_vir_g==(vir_bytes)m_ptr->IO_GRANT)) {
|
||||||
/* Process was writing when killed. Clean up output. */
|
/* Process was writing when killed. Clean up output. */
|
||||||
(*tp->tty_ocancel)(tp, 0);
|
#if DEAD_CODE
|
||||||
tp->tty_outleft = tp->tty_outcum = 0;
|
(*tp->tty_ocancel)(tp, 0);
|
||||||
}
|
#endif
|
||||||
|
r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
|
||||||
|
tp->tty_outleft = tp->tty_outcum = tp->tty_outrevived = 0;
|
||||||
|
}
|
||||||
if (tp->tty_ioreq != 0 && proc_nr == tp->tty_ioproc) {
|
if (tp->tty_ioreq != 0 && proc_nr == tp->tty_ioproc) {
|
||||||
/* Process was waiting for output to drain. */
|
/* Process was waiting for output to drain. */
|
||||||
tp->tty_ioreq = 0;
|
tp->tty_ioreq = 0;
|
||||||
}
|
}
|
||||||
tp->tty_events = 1;
|
tp->tty_events = 1;
|
||||||
tty_reply(TASK_REPLY, m_ptr->m_source, proc_nr, EINTR);
|
tty_reply(TASK_REPLY, m_ptr->m_source, proc_nr, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC int select_try(struct tty *tp, int ops)
|
PUBLIC int select_try(struct tty *tp, int ops)
|
||||||
@ -905,7 +862,7 @@ tty_t *tp; /* TTY to check for events. */
|
|||||||
|
|
||||||
/* Reply if enough bytes are available. */
|
/* Reply if enough bytes are available. */
|
||||||
if (tp->tty_incum >= tp->tty_min && tp->tty_inleft > 0) {
|
if (tp->tty_incum >= tp->tty_min && tp->tty_inleft > 0) {
|
||||||
if (tp->tty_inrepcode == REVIVE) {
|
if (tp->tty_inrepcode == TTY_REVIVE) {
|
||||||
notify(tp->tty_incaller);
|
notify(tp->tty_incaller);
|
||||||
tp->tty_inrevived = 1;
|
tp->tty_inrevived = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -952,10 +909,18 @@ register tty_t *tp; /* pointer to terminal to read from */
|
|||||||
tp->tty_inleft--;
|
tp->tty_inleft--;
|
||||||
if (++bp == bufend(buf)) {
|
if (++bp == bufend(buf)) {
|
||||||
/* Temp buffer full, copy to user space. */
|
/* Temp buffer full, copy to user space. */
|
||||||
sys_vircopy(SELF, D, (vir_bytes) buf,
|
if(tp->tty_in_safe) {
|
||||||
tp->tty_inproc, D, tp->tty_in_vir,
|
sys_safecopyto(tp->tty_inproc,
|
||||||
(vir_bytes) buflen(buf));
|
tp->tty_in_vir_g, tp->tty_in_vir_offset,
|
||||||
tp->tty_in_vir += buflen(buf);
|
(vir_bytes) buf,
|
||||||
|
(vir_bytes) buflen(buf), D);
|
||||||
|
tp->tty_in_vir_offset += buflen(buf);
|
||||||
|
} else {
|
||||||
|
sys_vircopy(SELF, D, (vir_bytes) buf,
|
||||||
|
tp->tty_inproc, D, tp->tty_in_vir_g,
|
||||||
|
(vir_bytes) buflen(buf));
|
||||||
|
tp->tty_in_vir_g += buflen(buf);
|
||||||
|
}
|
||||||
tp->tty_incum += buflen(buf);
|
tp->tty_incum += buflen(buf);
|
||||||
bp = buf;
|
bp = buf;
|
||||||
}
|
}
|
||||||
@ -975,15 +940,22 @@ register tty_t *tp; /* pointer to terminal to read from */
|
|||||||
if (bp > buf) {
|
if (bp > buf) {
|
||||||
/* Leftover characters in the buffer. */
|
/* Leftover characters in the buffer. */
|
||||||
count = bp - buf;
|
count = bp - buf;
|
||||||
sys_vircopy(SELF, D, (vir_bytes) buf,
|
if(tp->tty_in_safe) {
|
||||||
tp->tty_inproc, D, tp->tty_in_vir, (vir_bytes) count);
|
sys_safecopyto(tp->tty_inproc,
|
||||||
tp->tty_in_vir += count;
|
tp->tty_in_vir_g, tp->tty_in_vir_offset,
|
||||||
|
(vir_bytes) buf, (vir_bytes) count, D);
|
||||||
|
tp->tty_in_vir_offset += count;
|
||||||
|
} else {
|
||||||
|
sys_vircopy(SELF, D, (vir_bytes) buf,
|
||||||
|
tp->tty_inproc, D, tp->tty_in_vir_g, (vir_bytes) count);
|
||||||
|
tp->tty_in_vir_g += count;
|
||||||
|
}
|
||||||
tp->tty_incum += count;
|
tp->tty_incum += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Usually reply to the reader, possibly even if incum == 0 (EOF). */
|
/* Usually reply to the reader, possibly even if incum == 0 (EOF). */
|
||||||
if (tp->tty_inleft == 0) {
|
if (tp->tty_inleft == 0) {
|
||||||
if (tp->tty_inrepcode == REVIVE) {
|
if (tp->tty_inrepcode == TTY_REVIVE) {
|
||||||
notify(tp->tty_incaller);
|
notify(tp->tty_incaller);
|
||||||
tp->tty_inrevived = 1;
|
tp->tty_inrevived = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -1398,13 +1370,21 @@ tty_t *tp;
|
|||||||
|
|
||||||
if (tp->tty_ioreq != TCDRAIN) {
|
if (tp->tty_ioreq != TCDRAIN) {
|
||||||
if (tp->tty_ioreq == TCSETSF) tty_icancel(tp);
|
if (tp->tty_ioreq == TCSETSF) tty_icancel(tp);
|
||||||
result = sys_vircopy(tp->tty_ioproc, D, tp->tty_iovir,
|
if(tp->tty_io_safe) {
|
||||||
|
result = sys_safecopyfrom(tp->tty_ioproc, tp->tty_iovir_g, 0,
|
||||||
|
(vir_bytes) &tp->tty_termios,
|
||||||
|
(vir_bytes) sizeof(tp->tty_termios), D);
|
||||||
|
} else {
|
||||||
|
result = sys_vircopy(tp->tty_ioproc, D, tp->tty_iovir_g,
|
||||||
SELF, D, (vir_bytes) &tp->tty_termios,
|
SELF, D, (vir_bytes) &tp->tty_termios,
|
||||||
(vir_bytes) sizeof(tp->tty_termios));
|
(vir_bytes) sizeof(tp->tty_termios));
|
||||||
|
}
|
||||||
setattr(tp);
|
setattr(tp);
|
||||||
}
|
}
|
||||||
tp->tty_ioreq = 0;
|
tp->tty_ioreq = 0;
|
||||||
tty_reply(REVIVE, tp->tty_iocaller, tp->tty_ioproc, result);
|
notify(tp->tty_iocaller);
|
||||||
|
tp->tty_iorevived = 1;
|
||||||
|
tp->tty_iostatus = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
@ -1463,7 +1443,11 @@ tty_t *tp;
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* tty_reply *
|
* tty_reply *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void tty_reply(code, replyee, proc_nr, status)
|
PUBLIC void
|
||||||
|
tty_reply_f(
|
||||||
|
file, line, code, replyee, proc_nr, status)
|
||||||
|
char *file;
|
||||||
|
int line;
|
||||||
int code; /* TASK_REPLY or REVIVE */
|
int code; /* TASK_REPLY or REVIVE */
|
||||||
int replyee; /* destination address for the reply */
|
int replyee; /* destination address for the reply */
|
||||||
int proc_nr; /* to whom should the reply go? */
|
int proc_nr; /* to whom should the reply go? */
|
||||||
@ -1476,8 +1460,17 @@ int status; /* reply code */
|
|||||||
tty_mess.REP_ENDPT = proc_nr;
|
tty_mess.REP_ENDPT = proc_nr;
|
||||||
tty_mess.REP_STATUS = status;
|
tty_mess.REP_STATUS = status;
|
||||||
|
|
||||||
|
/* TTY is not supposed to send a TTY_REVIVE message. The
|
||||||
|
* REVIVE message is gone, TTY_REVIVE is only used as an internal
|
||||||
|
* placeholder for something that is not supposed to be a message.
|
||||||
|
*/
|
||||||
|
if(code == TTY_REVIVE) {
|
||||||
|
panicing = 1;
|
||||||
|
printf("%s:%d: ", file, line);
|
||||||
|
panic("TTY","tty_reply sending TTY_REVIVE", NO_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
if ((status = send(replyee, &tty_mess)) != OK) {
|
if ((status = send(replyee, &tty_mess)) != OK) {
|
||||||
printf("TTY: couldn't reply to %d\n", replyee);
|
|
||||||
panic("TTY","tty_reply failed, status\n", status);
|
panic("TTY","tty_reply failed, status\n", status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1496,9 +1489,11 @@ int sig; /* SIGINT, SIGQUIT, SIGKILL or SIGHUP */
|
|||||||
*/
|
*/
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (tp->tty_pgrp != 0)
|
if (tp->tty_pgrp != 0) {
|
||||||
if (OK != (status = sys_kill(tp->tty_pgrp, sig)))
|
if (OK != (status = sys_kill(tp->tty_pgrp, sig))) {
|
||||||
panic("TTY","Error, call to sys_kill failed", status);
|
panic("TTY","Error, call to sys_kill failed", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(tp->tty_termios.c_lflag & NOFLSH)) {
|
if (!(tp->tty_termios.c_lflag & NOFLSH)) {
|
||||||
tp->tty_incount = tp->tty_eotct = 0; /* kill earlier input */
|
tp->tty_incount = tp->tty_eotct = 0; /* kill earlier input */
|
||||||
@ -1685,341 +1680,3 @@ register message *m_ptr; /* pointer to message sent to the task */
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT
|
|
||||||
/*===========================================================================*
|
|
||||||
* compat_getp *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE int compat_getp(tp, sg)
|
|
||||||
tty_t *tp;
|
|
||||||
struct sgttyb *sg;
|
|
||||||
{
|
|
||||||
/* Translate an old TIOCGETP to the termios equivalent. */
|
|
||||||
int flgs;
|
|
||||||
|
|
||||||
sg->sg_erase = tp->tty_termios.c_cc[VERASE];
|
|
||||||
sg->sg_kill = tp->tty_termios.c_cc[VKILL];
|
|
||||||
sg->sg_ospeed = tspd2sgspd(cfgetospeed(&tp->tty_termios));
|
|
||||||
sg->sg_ispeed = tspd2sgspd(cfgetispeed(&tp->tty_termios));
|
|
||||||
|
|
||||||
flgs = 0;
|
|
||||||
|
|
||||||
/* XTABS - if OPOST and XTABS */
|
|
||||||
if ((tp->tty_termios.c_oflag & (OPOST|XTABS)) == (OPOST|XTABS))
|
|
||||||
flgs |= 0006000;
|
|
||||||
|
|
||||||
/* BITS5..BITS8 - map directly to CS5..CS8 */
|
|
||||||
flgs |= (tp->tty_termios.c_cflag & CSIZE) << (8-2);
|
|
||||||
|
|
||||||
/* EVENP - if PARENB and not PARODD */
|
|
||||||
if ((tp->tty_termios.c_cflag & (PARENB|PARODD)) == PARENB)
|
|
||||||
flgs |= 0000200;
|
|
||||||
|
|
||||||
/* ODDP - if PARENB and PARODD */
|
|
||||||
if ((tp->tty_termios.c_cflag & (PARENB|PARODD)) == (PARENB|PARODD))
|
|
||||||
flgs |= 0000100;
|
|
||||||
|
|
||||||
/* RAW - if not ICANON and not ISIG */
|
|
||||||
if (!(tp->tty_termios.c_lflag & (ICANON|ISIG)))
|
|
||||||
flgs |= 0000040;
|
|
||||||
|
|
||||||
/* CRMOD - if ICRNL */
|
|
||||||
if (tp->tty_termios.c_iflag & ICRNL)
|
|
||||||
flgs |= 0000020;
|
|
||||||
|
|
||||||
/* ECHO - if ECHO */
|
|
||||||
if (tp->tty_termios.c_lflag & ECHO)
|
|
||||||
flgs |= 0000010;
|
|
||||||
|
|
||||||
/* CBREAK - if not ICANON and ISIG */
|
|
||||||
if ((tp->tty_termios.c_lflag & (ICANON|ISIG)) == ISIG)
|
|
||||||
flgs |= 0000002;
|
|
||||||
|
|
||||||
sg->sg_flags = flgs;
|
|
||||||
return(OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* compat_getc *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE int compat_getc(tp, tc)
|
|
||||||
tty_t *tp;
|
|
||||||
struct tchars *tc;
|
|
||||||
{
|
|
||||||
/* Translate an old TIOCGETC to the termios equivalent. */
|
|
||||||
|
|
||||||
tc->t_intrc = tp->tty_termios.c_cc[VINTR];
|
|
||||||
tc->t_quitc = tp->tty_termios.c_cc[VQUIT];
|
|
||||||
tc->t_startc = tp->tty_termios.c_cc[VSTART];
|
|
||||||
tc->t_stopc = tp->tty_termios.c_cc[VSTOP];
|
|
||||||
tc->t_brkc = tp->tty_termios.c_cc[VEOL];
|
|
||||||
tc->t_eofc = tp->tty_termios.c_cc[VEOF];
|
|
||||||
return(OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* compat_setp *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE int compat_setp(tp, sg)
|
|
||||||
tty_t *tp;
|
|
||||||
struct sgttyb *sg;
|
|
||||||
{
|
|
||||||
/* Translate an old TIOCSETP to the termios equivalent. */
|
|
||||||
struct termios termios;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
termios = tp->tty_termios;
|
|
||||||
|
|
||||||
termios.c_cc[VERASE] = sg->sg_erase;
|
|
||||||
termios.c_cc[VKILL] = sg->sg_kill;
|
|
||||||
cfsetispeed(&termios, sgspd2tspd(sg->sg_ispeed & BYTE));
|
|
||||||
cfsetospeed(&termios, sgspd2tspd(sg->sg_ospeed & BYTE));
|
|
||||||
flags = sg->sg_flags;
|
|
||||||
|
|
||||||
/* Input flags */
|
|
||||||
|
|
||||||
/* BRKINT - not changed */
|
|
||||||
/* ICRNL - set if CRMOD is set and not RAW */
|
|
||||||
/* (CRMOD also controls output) */
|
|
||||||
termios.c_iflag &= ~ICRNL;
|
|
||||||
if ((flags & 0000020) && !(flags & 0000040))
|
|
||||||
termios.c_iflag |= ICRNL;
|
|
||||||
|
|
||||||
/* IGNBRK - not changed */
|
|
||||||
/* IGNCR - forced off (ignoring cr's is not supported) */
|
|
||||||
termios.c_iflag &= ~IGNCR;
|
|
||||||
|
|
||||||
/* IGNPAR - not changed */
|
|
||||||
/* INLCR - forced off (mapping nl's to cr's is not supported) */
|
|
||||||
termios.c_iflag &= ~INLCR;
|
|
||||||
|
|
||||||
/* INPCK - not changed */
|
|
||||||
/* ISTRIP - not changed */
|
|
||||||
/* IXOFF - not changed */
|
|
||||||
/* IXON - forced on if not RAW */
|
|
||||||
termios.c_iflag &= ~IXON;
|
|
||||||
if (!(flags & 0000040))
|
|
||||||
termios.c_iflag |= IXON;
|
|
||||||
|
|
||||||
/* PARMRK - not changed */
|
|
||||||
|
|
||||||
/* Output flags */
|
|
||||||
|
|
||||||
/* OPOST - forced on if not RAW */
|
|
||||||
termios.c_oflag &= ~OPOST;
|
|
||||||
if (!(flags & 0000040))
|
|
||||||
termios.c_oflag |= OPOST;
|
|
||||||
|
|
||||||
/* ONLCR - forced on if CRMOD */
|
|
||||||
termios.c_oflag &= ~ONLCR;
|
|
||||||
if (flags & 0000020)
|
|
||||||
termios.c_oflag |= ONLCR;
|
|
||||||
|
|
||||||
/* XTABS - forced on if XTABS */
|
|
||||||
termios.c_oflag &= ~XTABS;
|
|
||||||
if (flags & 0006000)
|
|
||||||
termios.c_oflag |= XTABS;
|
|
||||||
|
|
||||||
/* CLOCAL - not changed */
|
|
||||||
/* CREAD - forced on (receiver is always enabled) */
|
|
||||||
termios.c_cflag |= CREAD;
|
|
||||||
|
|
||||||
/* CSIZE - CS5-CS8 correspond directly to BITS5-BITS8 */
|
|
||||||
termios.c_cflag = (termios.c_cflag & ~CSIZE) | ((flags & 0001400) >> (8-2));
|
|
||||||
|
|
||||||
/* CSTOPB - not changed */
|
|
||||||
/* HUPCL - not changed */
|
|
||||||
/* PARENB - set if EVENP or ODDP is set */
|
|
||||||
termios.c_cflag &= ~PARENB;
|
|
||||||
if (flags & (0000200|0000100))
|
|
||||||
termios.c_cflag |= PARENB;
|
|
||||||
|
|
||||||
/* PARODD - set if ODDP is set */
|
|
||||||
termios.c_cflag &= ~PARODD;
|
|
||||||
if (flags & 0000100)
|
|
||||||
termios.c_cflag |= PARODD;
|
|
||||||
|
|
||||||
/* Local flags */
|
|
||||||
|
|
||||||
/* ECHO - set if ECHO is set */
|
|
||||||
termios.c_lflag &= ~ECHO;
|
|
||||||
if (flags & 0000010)
|
|
||||||
termios.c_lflag |= ECHO;
|
|
||||||
|
|
||||||
/* ECHOE - not changed */
|
|
||||||
/* ECHOK - not changed */
|
|
||||||
/* ECHONL - not changed */
|
|
||||||
/* ICANON - set if neither CBREAK nor RAW */
|
|
||||||
termios.c_lflag &= ~ICANON;
|
|
||||||
if (!(flags & (0000002|0000040)))
|
|
||||||
termios.c_lflag |= ICANON;
|
|
||||||
|
|
||||||
/* IEXTEN - set if not RAW */
|
|
||||||
/* ISIG - set if not RAW */
|
|
||||||
termios.c_lflag &= ~(IEXTEN|ISIG);
|
|
||||||
if (!(flags & 0000040))
|
|
||||||
termios.c_lflag |= (IEXTEN|ISIG);
|
|
||||||
|
|
||||||
/* NOFLSH - not changed */
|
|
||||||
/* TOSTOP - not changed */
|
|
||||||
|
|
||||||
tp->tty_termios = termios;
|
|
||||||
setattr(tp);
|
|
||||||
return(OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* compat_setc *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE int compat_setc(tp, tc)
|
|
||||||
tty_t *tp;
|
|
||||||
struct tchars *tc;
|
|
||||||
{
|
|
||||||
/* Translate an old TIOCSETC to the termios equivalent. */
|
|
||||||
struct termios termios;
|
|
||||||
|
|
||||||
termios = tp->tty_termios;
|
|
||||||
|
|
||||||
termios.c_cc[VINTR] = tc->t_intrc;
|
|
||||||
termios.c_cc[VQUIT] = tc->t_quitc;
|
|
||||||
termios.c_cc[VSTART] = tc->t_startc;
|
|
||||||
termios.c_cc[VSTOP] = tc->t_stopc;
|
|
||||||
termios.c_cc[VEOL] = tc->t_brkc;
|
|
||||||
termios.c_cc[VEOF] = tc->t_eofc;
|
|
||||||
|
|
||||||
tp->tty_termios = termios;
|
|
||||||
setattr(tp);
|
|
||||||
return(OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Table of termios line speed to sgtty line speed translations. All termios
|
|
||||||
* speeds are present even if sgtty didn't know about them. (Now it does.)
|
|
||||||
*/
|
|
||||||
PRIVATE struct s2s {
|
|
||||||
speed_t tspd;
|
|
||||||
u8_t sgspd;
|
|
||||||
} ts2sgs[] = {
|
|
||||||
{ B0, 0 },
|
|
||||||
{ B50, 50 },
|
|
||||||
{ B75, 75 },
|
|
||||||
{ B110, 1 },
|
|
||||||
{ B134, 134 },
|
|
||||||
{ B200, 2 },
|
|
||||||
{ B300, 3 },
|
|
||||||
{ B600, 6 },
|
|
||||||
{ B1200, 12 },
|
|
||||||
{ B1800, 18 },
|
|
||||||
{ B2400, 24 },
|
|
||||||
{ B4800, 48 },
|
|
||||||
{ B9600, 96 },
|
|
||||||
{ B19200, 192 },
|
|
||||||
{ B38400, 195 },
|
|
||||||
{ B57600, 194 },
|
|
||||||
{ B115200, 193 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* tspd2sgspd *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE int tspd2sgspd(tspd)
|
|
||||||
speed_t tspd;
|
|
||||||
{
|
|
||||||
/* Translate a termios speed to sgtty speed. */
|
|
||||||
struct s2s *s;
|
|
||||||
|
|
||||||
for (s = ts2sgs; s < ts2sgs + sizeof(ts2sgs)/sizeof(ts2sgs[0]); s++) {
|
|
||||||
if (s->tspd == tspd) return(s->sgspd);
|
|
||||||
}
|
|
||||||
return 96;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* sgspd2tspd *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE speed_t sgspd2tspd(sgspd)
|
|
||||||
int sgspd;
|
|
||||||
{
|
|
||||||
/* Translate a sgtty speed to termios speed. */
|
|
||||||
struct s2s *s;
|
|
||||||
|
|
||||||
for (s = ts2sgs; s < ts2sgs + sizeof(ts2sgs)/sizeof(ts2sgs[0]); s++) {
|
|
||||||
if (s->sgspd == sgspd) return(s->tspd);
|
|
||||||
}
|
|
||||||
return B9600;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLE_BINCOMPAT
|
|
||||||
/*===========================================================================*
|
|
||||||
* do_ioctl_compat *
|
|
||||||
*===========================================================================*/
|
|
||||||
PRIVATE void do_ioctl_compat(tp, m_ptr)
|
|
||||||
tty_t *tp;
|
|
||||||
message *m_ptr;
|
|
||||||
{
|
|
||||||
/* Handle the old sgtty ioctl's that packed the sgtty or tchars struct into
|
|
||||||
* the Minix message. Efficient then, troublesome now.
|
|
||||||
*/
|
|
||||||
int minor, proc, func, result, r;
|
|
||||||
long flags, erki, spek;
|
|
||||||
u8_t erase, kill, intr, quit, xon, xoff, brk, eof, ispeed, ospeed;
|
|
||||||
struct sgttyb sg;
|
|
||||||
struct tchars tc;
|
|
||||||
message reply_mess;
|
|
||||||
|
|
||||||
minor = m_ptr->TTY_LINE;
|
|
||||||
proc = m_ptr->IO_ENDPT;
|
|
||||||
func = m_ptr->REQUEST;
|
|
||||||
spek = m_ptr->m2_l1;
|
|
||||||
flags = m_ptr->m2_l2;
|
|
||||||
|
|
||||||
switch(func)
|
|
||||||
{
|
|
||||||
case (('t'<<8) | 8): /* TIOCGETP */
|
|
||||||
r = compat_getp(tp, &sg);
|
|
||||||
erase = sg.sg_erase;
|
|
||||||
kill = sg.sg_kill;
|
|
||||||
ispeed = sg.sg_ispeed;
|
|
||||||
ospeed = sg.sg_ospeed;
|
|
||||||
flags = sg.sg_flags;
|
|
||||||
erki = ((long)ospeed<<24) | ((long)ispeed<<16) | ((long)erase<<8) |kill;
|
|
||||||
break;
|
|
||||||
case (('t'<<8) | 18): /* TIOCGETC */
|
|
||||||
r = compat_getc(tp, &tc);
|
|
||||||
intr = tc.t_intrc;
|
|
||||||
quit = tc.t_quitc;
|
|
||||||
xon = tc.t_startc;
|
|
||||||
xoff = tc.t_stopc;
|
|
||||||
brk = tc.t_brkc;
|
|
||||||
eof = tc.t_eofc;
|
|
||||||
erki = ((long)intr<<24) | ((long)quit<<16) | ((long)xon<<8) | xoff;
|
|
||||||
flags = (eof << 8) | brk;
|
|
||||||
break;
|
|
||||||
case (('t'<<8) | 17): /* TIOCSETC */
|
|
||||||
tc.t_stopc = (spek >> 0) & 0xFF;
|
|
||||||
tc.t_startc = (spek >> 8) & 0xFF;
|
|
||||||
tc.t_quitc = (spek >> 16) & 0xFF;
|
|
||||||
tc.t_intrc = (spek >> 24) & 0xFF;
|
|
||||||
tc.t_brkc = (flags >> 0) & 0xFF;
|
|
||||||
tc.t_eofc = (flags >> 8) & 0xFF;
|
|
||||||
r = compat_setc(tp, &tc);
|
|
||||||
break;
|
|
||||||
case (('t'<<8) | 9): /* TIOCSETP */
|
|
||||||
sg.sg_erase = (spek >> 8) & 0xFF;
|
|
||||||
sg.sg_kill = (spek >> 0) & 0xFF;
|
|
||||||
sg.sg_ispeed = (spek >> 16) & 0xFF;
|
|
||||||
sg.sg_ospeed = (spek >> 24) & 0xFF;
|
|
||||||
sg.sg_flags = flags;
|
|
||||||
r = compat_setp(tp, &sg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
r = ENOTTY;
|
|
||||||
}
|
|
||||||
reply_mess.m_type = TASK_REPLY;
|
|
||||||
reply_mess.REP_ENDPT = m_ptr->IO_ENDPT;
|
|
||||||
reply_mess.REP_STATUS = r;
|
|
||||||
reply_mess.m2_l1 = erki;
|
|
||||||
reply_mess.m2_l2 = flags;
|
|
||||||
send(m_ptr->m_source, &reply_mess);
|
|
||||||
}
|
|
||||||
#endif /* ENABLE_BINCOMPAT */
|
|
||||||
#endif /* ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT */
|
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,8 @@
|
|||||||
#undef lock
|
#undef lock
|
||||||
#undef unlock
|
#undef unlock
|
||||||
|
|
||||||
|
#define TTY_REVIVE 6767
|
||||||
|
|
||||||
/* First minor numbers for the various classes of TTY devices. */
|
/* First minor numbers for the various classes of TTY devices. */
|
||||||
#define CONS_MINOR 0
|
#define CONS_MINOR 0
|
||||||
#define LOG_MINOR 15
|
#define LOG_MINOR 15
|
||||||
@ -66,20 +68,27 @@ typedef struct tty {
|
|||||||
char tty_inrevived; /* set to 1 if revive callback is pending */
|
char tty_inrevived; /* set to 1 if revive callback is pending */
|
||||||
int tty_incaller; /* process that made the call (usually FS) */
|
int tty_incaller; /* process that made the call (usually FS) */
|
||||||
int tty_inproc; /* process that wants to read from tty */
|
int tty_inproc; /* process that wants to read from tty */
|
||||||
vir_bytes tty_in_vir; /* virtual address where data is to go */
|
vir_bytes tty_in_vir_g; /* address or grant where data is to go */
|
||||||
|
vir_bytes tty_in_vir_offset; /* offset into grant */
|
||||||
|
int tty_in_safe; /* nonzero: safecopies (in_vir is grantid) */
|
||||||
int tty_inleft; /* how many chars are still needed */
|
int tty_inleft; /* how many chars are still needed */
|
||||||
int tty_incum; /* # chars input so far */
|
int tty_incum; /* # chars input so far */
|
||||||
int tty_outrepcode; /* reply code, TASK_REPLY or REVIVE */
|
int tty_outrepcode; /* reply code, TASK_REPLY or REVIVE */
|
||||||
int tty_outrevived; /* set to 1 if revive callback is pending */
|
int tty_outrevived; /* set to 1 if revive callback is pending */
|
||||||
int tty_outcaller; /* process that made the call (usually FS) */
|
int tty_outcaller; /* process that made the call (usually FS) */
|
||||||
int tty_outproc; /* process that wants to write to tty */
|
int tty_outproc; /* process that wants to write to tty */
|
||||||
vir_bytes tty_out_vir; /* virtual address where data comes from */
|
vir_bytes tty_out_vir_g; /* address or grant where data comes from */
|
||||||
|
vir_bytes tty_out_vir_offset; /* offset into grant */
|
||||||
|
int tty_out_safe; /* nonzero: safecopies (out_vir is grantid) */
|
||||||
int tty_outleft; /* # chars yet to be output */
|
int tty_outleft; /* # chars yet to be output */
|
||||||
int tty_outcum; /* # chars output so far */
|
int tty_outcum; /* # chars output so far */
|
||||||
int tty_iocaller; /* process that made the call (usually FS) */
|
int tty_iocaller; /* process that made the call (usually FS) */
|
||||||
|
int tty_iorevived; /* set to 1 if revive callback is pending */
|
||||||
int tty_ioproc; /* process that wants to do an ioctl */
|
int tty_ioproc; /* process that wants to do an ioctl */
|
||||||
|
int tty_iostatus; /* result */
|
||||||
int tty_ioreq; /* ioctl request code */
|
int tty_ioreq; /* ioctl request code */
|
||||||
vir_bytes tty_iovir; /* virtual address of ioctl buffer */
|
int tty_io_safe; /* safe copy mode? (iovir is grant id) */
|
||||||
|
vir_bytes tty_iovir_g; /* virtual address of ioctl buffer or grant */
|
||||||
|
|
||||||
/* select() data */
|
/* select() data */
|
||||||
int tty_select_ops; /* which operations are interesting */
|
int tty_select_ops; /* which operations are interesting */
|
||||||
@ -146,7 +155,8 @@ _PROTOTYPE( int in_process, (struct tty *tp, char *buf, int count) );
|
|||||||
_PROTOTYPE( void out_process, (struct tty *tp, char *bstart, char *bpos,
|
_PROTOTYPE( void out_process, (struct tty *tp, char *bstart, char *bpos,
|
||||||
char *bend, int *icount, int *ocount) );
|
char *bend, int *icount, int *ocount) );
|
||||||
_PROTOTYPE( void tty_wakeup, (clock_t now) );
|
_PROTOTYPE( void tty_wakeup, (clock_t now) );
|
||||||
_PROTOTYPE( void tty_reply, (int code, int replyee, int proc_nr,
|
#define tty_reply(c, r, p, s) tty_reply_f(__FILE__, __LINE__, (c), (r), (p), (s))
|
||||||
|
_PROTOTYPE( void tty_reply_f, (char *f, int l, int code, int replyee, int proc_nr,
|
||||||
int status) );
|
int status) );
|
||||||
_PROTOTYPE( int tty_devnop, (struct tty *tp, int try) );
|
_PROTOTYPE( int tty_devnop, (struct tty *tp, int try) );
|
||||||
_PROTOTYPE( int select_try, (struct tty *tp, int ops) );
|
_PROTOTYPE( int select_try, (struct tty *tp, int ops) );
|
||||||
@ -161,7 +171,7 @@ _PROTOTYPE( void rs_interrupt, (message *m) );
|
|||||||
_PROTOTYPE( void kputc, (int c) );
|
_PROTOTYPE( void kputc, (int c) );
|
||||||
_PROTOTYPE( void cons_stop, (void) );
|
_PROTOTYPE( void cons_stop, (void) );
|
||||||
_PROTOTYPE( void do_new_kmess, (message *m) );
|
_PROTOTYPE( void do_new_kmess, (message *m) );
|
||||||
_PROTOTYPE( void do_diagnostics, (message *m) );
|
_PROTOTYPE( void do_diagnostics, (message *m, int safe) );
|
||||||
_PROTOTYPE( void do_get_kmess, (message *m) );
|
_PROTOTYPE( void do_get_kmess, (message *m) );
|
||||||
_PROTOTYPE( void scr_init, (struct tty *tp) );
|
_PROTOTYPE( void scr_init, (struct tty *tp) );
|
||||||
_PROTOTYPE( void toggle_scroll, (void) );
|
_PROTOTYPE( void toggle_scroll, (void) );
|
||||||
@ -173,7 +183,7 @@ _PROTOTYPE( void do_video, (message *m) );
|
|||||||
/* keyboard.c */
|
/* keyboard.c */
|
||||||
_PROTOTYPE( void kb_init, (struct tty *tp) );
|
_PROTOTYPE( void kb_init, (struct tty *tp) );
|
||||||
_PROTOTYPE( void kb_init_once, (void) );
|
_PROTOTYPE( void kb_init_once, (void) );
|
||||||
_PROTOTYPE( int kbd_loadmap, (message *m) );
|
_PROTOTYPE( int kbd_loadmap, (message *m, int safe) );
|
||||||
_PROTOTYPE( void do_panic_dumps, (message *m) );
|
_PROTOTYPE( void do_panic_dumps, (message *m) );
|
||||||
_PROTOTYPE( void do_fkey_ctl, (message *m) );
|
_PROTOTYPE( void do_fkey_ctl, (message *m) );
|
||||||
_PROTOTYPE( void kbd_interrupt, (message *m) );
|
_PROTOTYPE( void kbd_interrupt, (message *m) );
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user