]> Zhao Yanbai Git Server - minix.git/commitdiff
. Safe I/O, ioctl() and DIAGNOSTICS variants conversion - safe copies,
authorBen Gras <ben@minix3.org>
Tue, 20 Jun 2006 09:02:54 +0000 (09:02 +0000)
committerBen Gras <ben@minix3.org>
Tue, 20 Jun 2006 09:02:54 +0000 (09:02 +0000)
  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

drivers/tty/Makefile
drivers/tty/console.c
drivers/tty/keyboard.c
drivers/tty/pty.c
drivers/tty/rs232.c
drivers/tty/tty.c
drivers/tty/tty.h

index a5d87b7822a678e74f951a912bed4b952a27f4bf..79edcd8c4ea168f77e1e49e3c2c278269b396281 100644 (file)
@@ -14,7 +14,7 @@ MAKE = exec make
 CC =   exec cc
 CFLAGS = -I$i
 LDFLAGS = -i
-LIBS = -lsys -lsysutil -ltimers
+LIBS = -lsysutil -lsys -ltimers
 
 OBJ = tty.o console.o vidcopy.o keyboard.o pty.o rs232.o 
 
index b49acb5452c348b88a6e20b50e9bd20bbf9fe6ac..57984be332735de93427a1a9bd07816388c3beb0 100644 (file)
@@ -167,13 +167,20 @@ int try;
    */
   do {
        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)
                break;
+           tp->tty_out_vir_g += count;
+       }
        tbuf = buf;
 
        /* Update terminal data structure. */
-       tp->tty_out_vir += count;
        tp->tty_outcum += count;
        tp->tty_outleft -= count;
 
@@ -777,7 +784,7 @@ PRIVATE void beep()
  *===========================================================================*/
 PUBLIC void do_video(message *m)
 {
-       int i, n, r, ops, watch;
+       int i, n, r, ops, watch, safe = 0;
        unsigned char c;
 
        /* Execute the requested device driver function. */
@@ -790,6 +797,9 @@ PUBLIC void do_video(message *m)
            case DEV_CLOSE:
                r= OK;
                break;
+           case DEV_IOCTL_S:
+               safe=1;
+               /* Fallthrough. */
            case DEV_IOCTL:
                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 */
 
                        /* 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,
                                SELF, D, (vir_bytes)&mapreq, sizeof(mapreq));
+                       }
                        if (r != OK)
                        {
                                tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT,
                                        r);
                                return;
                        }
-                       r= sys_vm_map(m->IO_ENDPT, do_map,
-                               (phys_bytes)mapreq.base, mapreq.size,
-                               mapreq.offset);
+
+                       /* In safe ioctl mode, the POSITION field contains
+                        * 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);
                        return;
                }
@@ -1057,20 +1079,27 @@ message *m;
 /*===========================================================================*
  *                             do_diagnostics                               *
  *===========================================================================*/
-PUBLIC void do_diagnostics(m_ptr)
+PUBLIC void do_diagnostics(m_ptr, safe)
 message *m_ptr;                        /* pointer to request message */
+int safe;
 {
 /* Print a string for a server. */
   char c;
   vir_bytes src;
-  int count;
+  int count, offset = 0;
   int result = OK;
-  int proc_nr = m_ptr->DIAG_ENDPT;
-  if (proc_nr == SELF) proc_nr = m_ptr->m_source;
+  int 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--) {
-       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;
                break;
        }
index 0238075278ea4ae9b9a21fd639b22e1b7e28f446..9b0357a230fdb26bbe3a6512a9f04763d539bf2d 100644 (file)
@@ -110,7 +110,9 @@ PRIVATE struct kbd
        int avail;
        int req_size;
        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 select_ops;
        int select_proc;
@@ -188,7 +190,7 @@ PRIVATE void handle_req(kbdp, m)
 struct kbd *kbdp;
 message *m;
 {
-       int i, n, r, ops, watch;
+       int i, n, r, ops, watch, safecopy = 0;
        unsigned char c;
 
        /* Execute the requested device driver function. */
@@ -209,6 +211,9 @@ message *m;
                        kbdp->avail= 0;
                r= OK;
                break;
+           case DEV_READ_S:
+               safecopy = 1;
+               /* Fallthrough. */
            case DEV_READ:       
                if (kbdp->req_size)
                {
@@ -221,7 +226,9 @@ message *m;
                        /* Should record proc */
                        kbdp->req_size= m->COUNT;
                        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;
                        r= SUSPEND;
                        break;
@@ -235,17 +242,27 @@ message *m;
                        n= KBD_BUFSZ-kbdp->offset;
                if (n <= 0)
                        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);
+               }
                if (r == OK)
                {
                        kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
                        kbdp->avail -= n;
                        r= n;
+               } else {
+                       printf("copy in read kbd failed: %d\n", r);
                }
 
                break;
 
+           case DEV_WRITE_S:
+               safecopy = 1;
+               /* Fallthrough. */
            case DEV_WRITE:
                if (kbdp != &kbdaux)
                {
@@ -260,8 +277,14 @@ message *m;
                 */
                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);
+                       }
                        if (r != OK)
                                break;
                        kbc_cmd1(KBC_WRITE_AUX, c);
@@ -290,14 +313,24 @@ message *m;
                        kbdp->select_proc= m->m_source;
                }
                break;
+           case DEV_IOCTL_S:
+                safecopy=1;
+                /* Fallthrough. */
            case DEV_IOCTL:
                if (kbdp == &kbd && m->TTY_REQUEST == KIOCSLEDS)
                {
                        kio_leds_t leds;
                        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));
+                       }
                        if (r != OK)
                                break;
                        b= 0;
@@ -330,8 +363,14 @@ message *m;
                        kio_bell_t bell;
                        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));
+                       }
                        if (r != OK)
                                break;
 
@@ -376,17 +415,23 @@ message *m;
                if (n <= 0)
                        panic("TTY", "kbd_status: bad n", n);
                kbdp->req_size= 0;
-               r= sys_vircopy(SELF, D, (vir_bytes)&kbdp->buf[kbdp->offset], 
-                       kbdp->req_proc, D, kbdp->req_addr, n);
+               if(kbdp->req_safe) {
+                 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)
                {
                        kbdp->offset= (kbdp->offset+n) % KBD_BUFSZ;
                        kbdp->avail -= n;
                        r= n;
-               }
+               } else printf("copy in revive kbd failed: %d\n", r);
 
                m->m_type = DEV_REVIVE;
                m->REP_ENDPT= kbdp->req_proc;
+               m->REP_IO_GRANT= kbdp->req_addr_g;
                m->REP_STATUS= r;
                return 1;
        }
@@ -472,15 +517,18 @@ message *m_ptr;
        /* raw scan codes or aux data */
        if (kbdp->avail >= KBD_BUFSZ)
        {
+#if 0
                printf("kbd_interrupt: %s buffer is full\n",
                        isaux ? "kbdaux" : "keyboard");
+#endif
                return; /* Buffer is full */
        }
         o= (kbdp->offset + kbdp->avail) % KBD_BUFSZ;
         kbdp->buf[o]= scode;
         kbdp->avail++;
-        if (kbdp->req_size)
+        if (kbdp->req_size) {
                notify(kbdp->incaller);
+        }
         if (kbdp->select_ops & SEL_RD)
                notify(kbdp->select_proc);
         return;
@@ -583,14 +631,18 @@ PRIVATE void kbd_send()
        if (kbdout.expect_ack)
                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))
        {
                printf("not sending 1: sb = 0x%x\n", sb);
                return;
        }
        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))
        {
                printf("not sending 2: sb = 0x%x\n", sb);
@@ -601,7 +653,9 @@ PRIVATE void kbd_send()
 #if 0
        printf("sending byte 0x%x to keyboard\n", kbdout.buf[kbdout.offset]);
 #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.avail--;
        kbdout.expect_ack= 1;
@@ -734,7 +788,8 @@ PRIVATE void kbc_cmd0(cmd)
 int cmd;
 {
        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;
 {
        kb_wait();
-       sys_outb(KB_COMMAND, cmd);
+       if(sys_outb(KB_COMMAND, cmd) != OK)
+               printf("kbc_cmd1: 1 sys_outb failed\n");
        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
 #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)
                {
                        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 DEBUG
@@ -819,6 +878,8 @@ PRIVATE int kb_wait()
   retries = MAX_KB_BUSY_RETRIES + 1;   /* wait until not busy */
   do {
       s = sys_inb(KB_STATUS, &status);
+      if(s != OK)
+       printf("kb_wait: sys_inb failed: %d\n", s);
       if (status & KB_OUT_FULL) {
          if (scan_keyboard(&byte, &isaux))
          {
@@ -847,6 +908,8 @@ PRIVATE int kb_ack()
   retries = MAX_KB_ACK_RETRIES + 1;
   do {
       s = sys_inb(KEYBD, &u8val);
+       if(s != OK)
+               printf("kb_ack: sys_inb failed: %d\n", s);
       if (u8val == KB_ACK)     
           break;               /* wait for ack */
   } while(--retries != 0);     /* continue unless timeout */
@@ -925,14 +988,20 @@ PUBLIC void kb_init_once(void)
 /*===========================================================================*
  *                             kbd_loadmap                                  *
  *===========================================================================*/
-PUBLIC int kbd_loadmap(m)
+PUBLIC int kbd_loadmap(m, safe)
 message *m;
+int safe;
 {
 /* Load a new keymap. */
   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, 
        (vir_bytes) sizeof(keymap));
+  }
   return(result);
 }
 
@@ -1137,30 +1206,35 @@ int *isauxp;
   
   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 */
-  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[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 */
 #else
   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 (kbdout.avail && !kbdout.expect_ack)
                kbd_send();
        return 0;
   }
-  sys_inb(KEYBD, &b);
+  if(sys_inb(KEYBD, &b) != OK)
+       printf("scan_keyboard: 2 sys_inb failed\n");
 #if 0
   printf("got byte 0x%x from %s\n", b, (sb & KB_AUX_BYTE) ? "AUX" : "keyboard");
 #endif
   if (!(sb & KB_AUX_BYTE) && b == KB_ACK && kbdout.expect_ack)
   {
-#if 1
+#if 0
        printf("got ACK from keyboard\n");
 #endif
        kbdout.expect_ack= 0;
index 9e3ffd4ae4f5ca9365637a33439bb34f4451a3ff..76b38dce2ec5c029de6e032730fc8fe1295f524b 100644 (file)
@@ -36,7 +36,9 @@ typedef struct pty {
   char         rdsendreply;    /* send a reply (instead of notify) */
   int          rdcaller;       /* process making the call (usually FS) */
   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          rdcum;          /* # bytes written so far */
 
@@ -44,14 +46,16 @@ typedef struct pty {
   char         wrsendreply;    /* send a reply (instead of notify) */
   int          wrcaller;       /* process making the call (usually FS) */
   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          wrcum;          /* # bytes written so far */
 
   /* Output buffer. */
   int          ocount;         /* # characters in the 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. */
   int          select_ops,     /* Which operations do we want to know about? */
@@ -86,8 +90,12 @@ message *m_ptr;
   pty_t *pp = tp->tty_priv;
   int r;
   phys_bytes p;
+  int safe = 0;
 
   switch (m_ptr->m_type) {
+    case DEV_READ_S:
+       safe=1;
+       /* fallthrough */
     case DEV_READ:
        /* Check, store information on the reader, do I/O. */
        if (pp->state & TTY_CLOSED) {
@@ -114,21 +122,31 @@ message *m_ptr;
        pp->rdsendreply = TRUE;
        pp->rdcaller = m_ptr->m_source;
        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;
        pty_start(pp);
        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) {
                r = EAGAIN;                             /* don't suspend */
                pp->rdleft = pp->rdcum = 0;
-       } else {
+       } else
+#endif
+       {
                r = SUSPEND;                            /* do suspend */
                pp->rdsendreply = FALSE;
        }
        break;
 
+    case DEV_WRITE_S:
+       safe=1;
+       /* fallthrough */
     case DEV_WRITE:
        /* Check, store information on the writer, do I/O. */
        if (pp->state & TTY_CLOSED) {
@@ -156,15 +174,22 @@ message *m_ptr;
        pp->wrsendreply = TRUE;
        pp->wrcaller = m_ptr->m_source;
        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;
        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 */
                r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
                pp->wrleft = pp->wrcum = 0;
-       } else {
+       } else
+#endif
+       {
                pp->wrsendreply = FALSE;                        /* do suspend */
                r = SUSPEND;
        }
@@ -192,15 +217,17 @@ message *m_ptr;
        break;
 
     case CANCEL:
+       r = EINTR;
        if (m_ptr->IO_ENDPT == pp->rdproc) {
                /* Cancel a read from a PTY. */
+               r = pp->rdcum > 0 ? pp->rdcum : EAGAIN;
                pp->rdleft = pp->rdcum = 0;
        }
        if (m_ptr->IO_ENDPT == pp->wrproc) {
                /* Cancel a write to a PTY. */
+               r = pp->wrcum > 0 ? pp->wrcum : EAGAIN;
                pp->wrleft = pp->wrcum = 0;
        }
-       r = EINTR;
        break;
 
     default:
@@ -227,9 +254,14 @@ int try;
   if (pp->state & PTY_CLOSED) {
        if (try) return 1;
        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_outleft = tp->tty_outcum = 0;
+                       tp->tty_outleft = tp->tty_outcum = 0;
+               }
        }
        return;
   }
@@ -245,10 +277,16 @@ int try;
                break;
 
        /* 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) {
+         if ((s = sys_safecopyfrom(tp->tty_outproc, tp->tty_out_vir_g,
+               tp->tty_out_vir_offset, (vir_bytes) pp->ohead, count, D))!=OK) {
+               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) {
-               printf("pty tty%d: copy failed (error %d)\n",  s);
                break;
+         }
        }
 
        /* Perform output processing on the output buffer. */
@@ -263,13 +301,21 @@ int try;
        if ((pp->ohead += ocount) >= bufend(pp->obuf))
                pp->ohead -= buflen(pp->obuf);
        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;
        if ((tp->tty_outleft -= count) == 0) {
                /* 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_outcum = 0;
+                       tp->tty_outcum = 0;
+               }
        }
   }
   pty_finish(pp);
@@ -319,16 +365,24 @@ pty_t *pp;
        if (count == 0) break;
 
        /* Copy from the output buffer to the readers address space. */
-       if ((s = sys_vircopy(SELF, D, (vir_bytes)pp->otail,
-               (vir_bytes) pp->rdproc, D, (vir_bytes) pp->rdvir, (phys_bytes) count)) != OK) {
-               printf("pty tty%d: copy failed (error %d)\n",  s);
+       if (pp->rdsafe) {
+         if((s = sys_safecopyto(pp->rdproc, pp->rdvir_g,
+               pp->rdvir_offset, (vir_bytes) pp->otail, count, D)) != OK) {
                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. */
        pp->ocount -= count;
        if ((pp->otail += count) == bufend(pp->obuf)) pp->otail = pp->obuf;
-       pp->rdvir += count;
        pp->rdcum += count;
        pp->rdleft -= count;
   }
@@ -370,9 +424,14 @@ int try;
   if (pp->state & PTY_CLOSED) {
        if (try) return 1;
        if (tp->tty_inleft > 0) {
-               tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc,
-                                                               tp->tty_incum);
-               tp->tty_inleft = tp->tty_incum = 0;
+               if(tp->tty_inrepcode == TTY_REVIVE) {
+                       notify(tp->tty_incaller);
+                       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;
   }
@@ -387,17 +446,26 @@ int try;
        int s;
 
        /* 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) {
                printf("pty: copy failed (error %d)\n", s);
                break;
+         }
+         pp->wrvir_g++;
        }
 
        /* Input processing. */
        if (in_process(tp, &c, 1) == 0) break;
 
        /* PTY writer bookkeeping. */
-       pp->wrvir++;
        pp->wrcum++;
        if (--pp->wrleft == 0) {
                if (pp->wrsendreply) {
@@ -447,7 +515,6 @@ int try;
   pty_t *pp = tp->tty_priv;
 
   if (pp->wrleft > 0) {
-       assert(!pp->wrsendreply);
        pp->wrcum += pp->wrleft;
        pp->wrleft= 0;
        notify(pp->wrcaller);
@@ -512,6 +579,7 @@ PUBLIC int pty_status(message *m_ptr)
                {
                        m_ptr->m_type = DEV_REVIVE;
                        m_ptr->REP_ENDPT = pp->rdproc;
+                       m_ptr->REP_IO_GRANT = pp->rdvir_g;
                        m_ptr->REP_STATUS = pp->rdcum;
 
                        pp->rdleft = pp->rdcum = 0;
@@ -525,6 +593,7 @@ PUBLIC int pty_status(message *m_ptr)
                {
                        m_ptr->m_type = DEV_REVIVE;
                        m_ptr->REP_ENDPT = pp->wrproc;
+                       m_ptr->REP_IO_GRANT = pp->wrvir_g;
                        if (pp->wrcum == 0)
                                m_ptr->REP_STATUS = EIO;
                        else
index ed6b384f5cfc1e75cb0f2e4bcae0e88c85f9bd21..bcaa6907e147bd3ed6e0557bae694eb48da697c6 100644 (file)
@@ -321,8 +321,13 @@ int try;
        if (try) return 1;
 
        /* 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);
+       }
 
        /* Perform output processing on the output buffer. */
        out_process(tp, rs->obuf, rs->ohead, bufend(rs->obuf), &count, &ocount);
@@ -338,7 +343,11 @@ int try;
        unlock();
        if ((rs->ohead += ocount) >= bufend(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;
        if ((tp->tty_outleft -= count) == 0) {
                /* Output is finished, reply to the writer. */
index fc5d3de43aedb80f4da49eda042b937c6b3cdaf4..64193dd97c637a86e801136c0eabd91d85d3ca52 100644 (file)
  *   DEV_STATUS:     FS wants to know status for SELECT or REVIVE
  *   CANCEL:         terminate a previous incomplete system call immediately
  *
- *    m_type      TTY_LINE   IO_ENDPT    COUNT   TTY_SPEK  TTY_FLAGS  ADDRESS
- * ---------------------------------------------------------------------------
- * | HARD_INT    |         |         |         |         |         |         |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | SYS_SIG     | sig set |         |         |         |         |         |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | DEV_READ    |minor dev| proc nr |  count  |         O_NONBLOCK| buf ptr |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | DEV_WRITE   |minor dev| proc nr |  count  |         |         | buf ptr |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | DEV_IOCTL   |minor dev| proc nr |func code|erase etc|  flags  |         |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | DEV_OPEN    |minor dev| proc nr | O_NOCTTY|         |         |         |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | DEV_CLOSE   |minor dev| proc nr |         |         |         |         |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | DEV_STATUS  |         |         |         |         |         |         |
- * |-------------+---------+---------+---------+---------+---------+---------|
- * | CANCEL      |minor dev| proc nr |         |         |         |         |
- * ---------------------------------------------------------------------------
+ *    m_type      TTY_LINE   IO_ENDPT    COUNT   TTY_SPEKS  ADDRESS
+ * -----------------------------------------------------------------
+ * | HARD_INT    |         |         |         |         |         |
+ * |-------------+---------+---------+---------+---------+---------|
+ * | SYS_SIG     | sig set |         |         |         |         |
+ * |-------------+---------+---------+---------+---------+---------|
+ * | DEV_READ    |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|         |
+ * |-------------+---------+---------+---------+---------+---------|
+ * | DEV_OPEN    |minor dev| proc nr | O_NOCTTY|         |         |
+ * |-------------+---------+---------+---------+---------+---------|
+ * | DEV_CLOSE   |minor dev| proc nr |         |         |         |
+ * |-------------+---------+---------+---------+---------+---------|
+ * | DEV_STATUS  |         |         |         |         |         |
+ * |-------------+---------+---------+---------+---------+---------|
+ * | CANCEL      |minor dev| proc nr |         |         |         |
+ * -----------------------------------------------------------------
  *
  * Changes:
  *   Jan 20, 2004   moved TTY driver to user-space  (Jorrit N. Herder)
@@ -58,9 +58,6 @@
 
 #include "../drivers.h"
 #include <termios.h>
-#if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT
-#include <sgtty.h>
-#endif
 #include <sys/ioc_tty.h>
 #include <signal.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 settimer, (tty_t *tty_ptr, int enable)                );
 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_close, (tty_t *tp, message *m_ptr)         );
-FORWARD _PROTOTYPE( void do_read, (tty_t *tp, message *m_ptr)          );
-FORWARD _PROTOTYPE( void do_write, (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, int s)  );
 FORWARD _PROTOTYPE( void do_select, (tty_t *tp, message *m_ptr)                );
 FORWARD _PROTOTYPE( void do_status, (message *m_ptr)                   );
 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 tty_icancel, (tty_t *tp)                      );
 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. */
 PRIVATE struct termios termios_defaults = {
@@ -165,17 +151,6 @@ PUBLIC void main(void)
   register struct proc *rp;
   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). */ 
   if (OK != (s=sys_getmachine(&machine))) {
     panic("TTY","Couldn't obtain kernel environment.", s);
@@ -229,13 +204,6 @@ PUBLIC void main(void)
        }
        case PROC_EVENT: {
                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;
        }
        case SYS_SIG: {                 /* system signal */
@@ -244,7 +212,10 @@ PUBLIC void main(void)
                continue;
        }
        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;
        case GET_KMESS:
                do_get_kmess(&tty_mess);
@@ -284,7 +255,8 @@ PUBLIC void main(void)
                tp = tty_addr(line - TTYPX_MINOR + NR_CONS + NR_RS_LINES);
        } else if ((line - PTYPX_MINOR) < NR_PTYS) {
                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);
                        continue;
                }
@@ -306,9 +278,12 @@ PUBLIC void main(void)
 
        /* Execute the requested device driver function. */
        switch (tty_mess.m_type) {
-           case DEV_READ:       do_read(tp, &tty_mess);          break;
-           case DEV_WRITE:      do_write(tp, &tty_mess);         break;
-           case DEV_IOCTL:      do_ioctl(tp, &tty_mess);         break;
+           case DEV_READ:       do_read(tp, &tty_mess, 0);       break;
+           case DEV_READ_S:     do_read(tp, &tty_mess, 1);       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_CLOSE:      do_close(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. */
                m_ptr->m_type = DEV_REVIVE;
                m_ptr->REP_ENDPT = tp->tty_inproc;
+               m_ptr->REP_IO_GRANT = tp->tty_in_vir_g;
                m_ptr->REP_STATUS = tp->tty_incum;
 
                tp->tty_inleft = tp->tty_incum = 0;
@@ -368,6 +344,7 @@ message *m_ptr;
                /* Suspended request finished. Send a REVIVE. */
                m_ptr->m_type = DEV_REVIVE;
                m_ptr->REP_ENDPT = tp->tty_outproc;
+               m_ptr->REP_IO_GRANT = tp->tty_out_vir_g;
                m_ptr->REP_STATUS = tp->tty_outcum;
 
                tp->tty_outcum = 0;
@@ -375,6 +352,16 @@ message *m_ptr;
                event_found = 1;
                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
@@ -398,36 +385,30 @@ message *m_ptr;
 /*===========================================================================*
  *                             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 message *m_ptr;       /* pointer to message sent to the task */
+int safe;                      /* use safecopies? */
 {
 /* A process wants to read from a terminal. */
   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
    * parameters are correct, do I/O.
    */
   if (tp->tty_inleft > 0) {
-       if (more_verbose) printf("do_read: EIO\n");
        r = EIO;
   } else
   if (m_ptr->COUNT <= 0) {
-       if (more_verbose) printf("do_read: EINVAL\n");
        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 {
        /* Copy information from the message to the tty struct. */
        tp->tty_inrepcode = TASK_REPLY;
        tp->tty_incaller = m_ptr->m_source;
        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;
 
        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 */
        }
 
-       /* There were no bytes in the input queue available, so either suspend
-        * the caller or break off the read if nonblocking.
+       /* There were no bytes in the input queue available, so suspend
+        * the caller.
         */
-       if (m_ptr->TTY_FLAGS & O_NONBLOCK) {
-               r = EAGAIN;                             /* cancel the read */
-               tp->tty_inleft = tp->tty_incum = 0;
-       } else {
-               r = SUSPEND;                            /* suspend the caller */
-               tp->tty_inrepcode = REVIVE;
-       }
+       r = SUSPEND;                            /* suspend the caller */
+       tp->tty_inrepcode = TTY_REVIVE;
   }
-  if (more_verbose) printf("do_read: replying %d\n", r);
   tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->IO_ENDPT, r);
   if (tp->tty_select_ops)
        select_retry(tp);
@@ -479,13 +454,13 @@ register message *m_ptr;  /* pointer to message sent to the task */
 /*===========================================================================*
  *                             do_write                                     *
  *===========================================================================*/
-PRIVATE void do_write(tp, m_ptr)
+PRIVATE void do_write(tp, m_ptr, safe)
 register tty_t *tp;
 register message *m_ptr;       /* pointer to message sent to the task */
+int safe;
 {
 /* A process wants to write on a terminal. */
   int r;
-  phys_bytes phys_addr;
 
   /* Check if there is already a process hanging in a write, check if the
    * parameters are correct, do I/O.
@@ -495,16 +470,14 @@ register message *m_ptr;  /* pointer to message sent to the task */
   } else
   if (m_ptr->COUNT <= 0) {
        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 {
        /* Copy message parameters to the tty structure. */
        tp->tty_outrepcode = TASK_REPLY;
        tp->tty_outcaller = m_ptr->m_source;
        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;
 
        /* Try to write. */
@@ -512,16 +485,11 @@ register message *m_ptr;  /* pointer to message sent to the task */
        if (tp->tty_outleft == 0) 
                return; /* already done */
 
-       /* None or not all the bytes could be written, so either suspend the
-        * caller or break off the write if nonblocking.
+       /* None or not all the bytes could be written, so suspend the
+        * caller.
         */
-       if (m_ptr->TTY_FLAGS & O_NONBLOCK) {            /* cancel the write */
-               r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
-               tp->tty_outleft = tp->tty_outcum = 0;
-       } else {
-               r = SUSPEND;                            /* suspend the caller */
-               tp->tty_outrepcode = REVIVE;
-       }
+       r = SUSPEND;                            /* suspend the caller */
+       tp->tty_outrepcode = TTY_REVIVE;
   }
   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                                     *
  *===========================================================================*/
-PRIVATE void do_ioctl(tp, m_ptr)
+PRIVATE void do_ioctl(tp, m_ptr, safe)
 register tty_t *tp;
 message *m_ptr;                        /* pointer to message sent to task */
+int safe;
 {
 /* Perform an IOCTL on this terminal. Posix termios calls are handled
  * by the IOCTL system call
@@ -540,10 +509,6 @@ message *m_ptr;                    /* pointer to message sent to task */
   int r;
   union {
        int i;
-#if ENABLE_SRCCOMPAT
-       struct sgttyb sg;
-       struct tchars tc;
-#endif
   } param;
   size_t size;
 
@@ -569,17 +534,6 @@ message *m_ptr;                    /* pointer to message sent to task */
         size = sizeof(struct winsize);
         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)
     case KIOCSMAP:     /* load keymap (Minix extension) */
         size = sizeof(keymap_t);
@@ -598,9 +552,14 @@ message *m_ptr;                    /* pointer to message sent to task */
   switch (m_ptr->TTY_REQUEST) {
     case TCGETS:
        /* 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, 
                (vir_bytes) size);
+       }
        break;
 
     case TCSETSW:
@@ -611,7 +570,8 @@ message *m_ptr;                     /* pointer to message sent to task */
                tp->tty_iocaller = m_ptr->m_source;
                tp->tty_ioproc = m_ptr->IO_ENDPT;
                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;
                break;
        }
@@ -620,15 +580,25 @@ message *m_ptr;                   /* pointer to message sent to task */
        /*FALL THROUGH*/
     case TCSETS:
        /* Set the termios attributes. */
-       r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
-               SELF, D, (vir_bytes) &tp->tty_termios, (vir_bytes) size);
+       if(safe) {
+           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;
        setattr(tp);
        break;
 
     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) &param.i, (vir_bytes) size, D);
+       } else {
+          r = sys_vircopy(m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
                SELF, D, (vir_bytes) &param.i, (vir_bytes) size);
+       }
        if (r != OK) break;
        switch (param.i) {
            case TCIFLUSH:      tty_icancel(tp);                            break;
@@ -639,8 +609,13 @@ message *m_ptr;                    /* pointer to message sent to task */
        break;
 
     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) &param.i, (vir_bytes) size, D);
+       } else {
+           r = sys_vircopy( m_ptr->IO_ENDPT, D, (vir_bytes) m_ptr->ADDRESS,
                SELF, D, (vir_bytes) &param.i, (vir_bytes) size);
+       }
        if (r != OK) break;
        switch (param.i) {
            case TCOOFF:
@@ -664,51 +639,31 @@ message *m_ptr;                   /* pointer to message sent to task */
        break;
 
     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, 
                (vir_bytes) size);
+       }
        break;
 
     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);
+       }
        sigchar(tp, SIGWINCH);
        break;
 
-#if ENABLE_SRCCOMPAT
-    case TIOCGETP:
-       compat_getp(tp, &param.sg);
-       r = sys_vircopy(SELF, D, (vir_bytes) &param.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) &param.sg, (vir_bytes) size);
-       if (r != OK) break;
-       compat_setp(tp, &param.sg);
-       break;
-
-    case TIOCGETC:
-       compat_getc(tp, &param.tc);
-       r = sys_vircopy(SELF, D, (vir_bytes) &param.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) &param.tc, (vir_bytes) size);
-       if (r != OK) break;
-       compat_setc(tp, &param.tc);
-       break;
-#endif
-
 #if (MACHINE == IBM_PC)
     case KIOCSMAP:
        /* 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;
 
     case TIOCSFON:
@@ -729,12 +684,7 @@ message *m_ptr;                    /* pointer to message sent to task */
     case TIOCGPGRP:     
     case TIOCSPGRP:    
     default:
-#if ENABLE_BINCOMPAT
-       do_ioctl_compat(tp, m_ptr);
-       return;
-#else
        r = ENOTTY;
-#endif
   }
 
   /* Send the reply. */
@@ -801,26 +751,33 @@ message *m_ptr;                   /* pointer to message sent to task */
 
   int proc_nr;
   int mode;
+  int r = EINTR;
 
   /* Check the parameters carefully, to avoid cancelling twice. */
   proc_nr = m_ptr->IO_ENDPT;
   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. */
-       tty_icancel(tp);
-       tp->tty_inleft = tp->tty_incum = 0;
-  }
-  if ((mode & W_BIT) && tp->tty_outleft != 0 && proc_nr == tp->tty_outproc) {
+       tty_icancel(tp); 
+       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 &&
+       (!tp->tty_out_safe || tp->tty_out_vir_g==(vir_bytes)m_ptr->IO_GRANT)) {
        /* Process was writing when killed.  Clean up output. */
-       (*tp->tty_ocancel)(tp, 0);
-       tp->tty_outleft = tp->tty_outcum = 0;
-  }
+#if DEAD_CODE
+       (*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) {
        /* Process was waiting for output to drain. */
        tp->tty_ioreq = 0;
   }
   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)
@@ -905,7 +862,7 @@ tty_t *tp;                  /* TTY to check for events. */
 
   /* Reply if enough bytes are available. */
   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);
                tp->tty_inrevived = 1;
        } else {
@@ -952,10 +909,18 @@ register tty_t *tp;               /* pointer to terminal to read from */
                tp->tty_inleft--;
                if (++bp == bufend(buf)) {
                        /* Temp buffer full, copy to user space. */
-                       sys_vircopy(SELF, D, (vir_bytes) buf, 
-                               tp->tty_inproc, D, tp->tty_in_vir,
-                               (vir_bytes) buflen(buf));
-                       tp->tty_in_vir += buflen(buf);
+                       if(tp->tty_in_safe) {
+                               sys_safecopyto(tp->tty_inproc,
+                                       tp->tty_in_vir_g, tp->tty_in_vir_offset,
+                                       (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);
                        bp = buf;
                }
@@ -975,15 +940,22 @@ register tty_t *tp;               /* pointer to terminal to read from */
   if (bp > buf) {
        /* Leftover characters in the buffer. */
        count = bp - buf;
-       sys_vircopy(SELF, D, (vir_bytes) buf, 
-               tp->tty_inproc, D, tp->tty_in_vir, (vir_bytes) count);
-       tp->tty_in_vir += count;
+       if(tp->tty_in_safe) {
+               sys_safecopyto(tp->tty_inproc,
+                       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;
   }
 
   /* Usually reply to the reader, possibly even if incum == 0 (EOF). */
   if (tp->tty_inleft == 0) {
-       if (tp->tty_inrepcode == REVIVE) {
+       if (tp->tty_inrepcode == TTY_REVIVE) {
                notify(tp->tty_incaller);
                tp->tty_inrevived = 1;
        } else {
@@ -1398,13 +1370,21 @@ tty_t *tp;
 
   if (tp->tty_ioreq != TCDRAIN) {
        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,
                        (vir_bytes) sizeof(tp->tty_termios));
+       }
        setattr(tp);
   }
   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                                    *
  *===========================================================================*/
-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 replyee;                   /* destination address for the reply */
 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_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) {
-       printf("TTY: couldn't reply to %d\n", replyee);
        panic("TTY","tty_reply failed, status\n", status);
   }
 }
@@ -1496,9 +1489,11 @@ int sig;                 /* SIGINT, SIGQUIT, SIGKILL or SIGHUP */
  */
   int status;
 
-  if (tp->tty_pgrp != 0) 
-      if (OK != (status = sys_kill(tp->tty_pgrp, sig)))
+  if (tp->tty_pgrp != 0)  {
+      if (OK != (status = sys_kill(tp->tty_pgrp, sig))) {
         panic("TTY","Error, call to sys_kill failed", status);
+      }
+  }
 
   if (!(tp->tty_termios.c_lflag & NOFLSH)) {
        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;
 }
 
-#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 */
-
index fb7da506efc293f490a288846aa1d9bd91094230..a3fba614f7d90af543fcf21f25e7662260bf26c5 100644 (file)
@@ -7,6 +7,8 @@
 #undef lock
 #undef unlock
 
+#define TTY_REVIVE     6767
+
 /* First minor numbers for the various classes of TTY devices. */
 #define CONS_MINOR        0
 #define LOG_MINOR        15
@@ -66,20 +68,27 @@ typedef struct tty {
   char tty_inrevived;          /* set to 1 if revive callback is pending */
   int tty_incaller;            /* process that made the call (usually FS) */
   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_incum;               /* # chars input so far */
   int tty_outrepcode;          /* reply code, TASK_REPLY or REVIVE */
   int tty_outrevived;          /* set to 1 if revive callback is pending */
   int tty_outcaller;           /* process that made the call (usually FS) */
   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_outcum;              /* # chars output so far */
   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_iostatus;            /* result */
   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 */
   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,
                                char *bend, int *icount, int *ocount)   );
 _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)     );
 _PROTOTYPE( int tty_devnop, (struct tty *tp, int try)                  );
 _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 cons_stop, (void)                                     );
 _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 scr_init, (struct tty *tp)                            );
 _PROTOTYPE( void toggle_scroll, (void)                                 );
@@ -173,7 +183,7 @@ _PROTOTYPE( void do_video, (message *m)                                     );
 /* keyboard.c */
 _PROTOTYPE( void kb_init, (struct tty *tp)                             );
 _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_fkey_ctl, (message *m)                             );
 _PROTOTYPE( void kbd_interrupt, (message *m)                           );