]> Zhao Yanbai Git Server - minix.git/commitdiff
PTY: add minimal support for TIOCPKT 49/3449/1
authorDavid van Moolenbroek <david@minix3.org>
Wed, 15 Feb 2017 19:27:45 +0000 (19:27 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 9 Mar 2017 23:40:08 +0000 (23:40 +0000)
With TIOCPKT enabled, each piece of output is preceded by a zero byte
on the PTY master.  In addition, a non-zero byte is a flags field
that conveys information about changes on the pseudoterminal.  This
patch implements the former, but not the latter.  That is enough to
get telnetd(8) going, however.  TIOCPKT support may be extended later.

Change-Id: I6ef9cc8cf1b4406147b088400fc8499684b62a30

minix/drivers/tty/pty/pty.c

index 1a6b556966c6aa2d03e841c40e09fb3b373bbc1b..9a1ec7a0ed06c7268be90227032e4fd5e6755bd6 100644 (file)
@@ -82,6 +82,7 @@ typedef struct pty {
 #define TTY_CLOSED     0x04    /* tty side has closed down */
 #define PTY_CLOSED     0x08    /* pty side has closed down */
 #define PTY_UNIX98     0x10    /* pty pair is Unix98 */
+#define PTY_PKTMODE    0x20    /* pty side is in packet mode (TIOCPKT) */
 
 static pty_t pty_table[NR_PTYS];       /* PTY bookkeeping */
 
@@ -347,6 +348,7 @@ static int pty_master_ioctl(devminor_t minor, unsigned long request,
   uid_t uid;
   struct ptmget pm;
   size_t len;
+  int r, val;
 
   if ((tp = line2tty(minor)) == NULL)
        return ENXIO;
@@ -386,6 +388,18 @@ static int pty_master_ioctl(devminor_t minor, unsigned long request,
                return EINVAL;
 
        return sys_safecopyto(endpt, grant, 0, (vir_bytes)&pm, sizeof(pm));
+
+  case TIOCPKT:
+       r = sys_safecopyfrom(endpt, grant, 0, (vir_bytes)&val, sizeof(val));
+       if (r != OK)
+               return r;
+
+       if (val)
+               pp->state |= PTY_PKTMODE;
+       else
+               pp->state &= ~PTY_PKTMODE;
+
+       return OK;
   }
 
   /* TODO: historically, all IOCTLs on the master are processed as if issued on
@@ -608,20 +622,36 @@ static void pty_start(pty_t *pp)
 {
 /* Transfer bytes written to the output buffer to the PTY reader. */
   int count;
+  char c;
 
   /* While there are things to do. */
   for (;;) {
-       int s;
        count = bufend(pp->obuf) - pp->otail;
        if (count > pp->ocount) count = pp->ocount;
+       if (count == 0 || pp->rdleft == 0) break;
+
+       /* If there is output at all, and packet mode is enabled, then prepend
+        * the output with a zero byte. This is absolutely minimal "support"
+        * for the TIOCPKT receipt mode to get telnetd(8) going. Implementing
+        * full support for all the TIOCPKT bits will require more work.
+        */
+       if (pp->rdcum == 0 && (pp->state & PTY_PKTMODE)) {
+               c = 0;
+               if (sys_safecopyto(pp->rdcaller, pp->rdgrant, 0, (vir_bytes)&c,
+                   sizeof(c)) != OK)
+                       break;
+
+               pp->rdcum++;
+               pp->rdleft--;
+       }
+
        if (count > pp->rdleft) count = pp->rdleft;
        if (count == 0) break;
 
        /* Copy from the output buffer to the readers address space. */
-       if((s = sys_safecopyto(pp->rdcaller, pp->rdgrant, pp->rdcum,
-               (vir_bytes) pp->otail, count)) != OK) {
+       if (sys_safecopyto(pp->rdcaller, pp->rdgrant, pp->rdcum,
+           (vir_bytes)pp->otail, count) != OK)
                break;
-       }
 
        /* Bookkeeping. */
        pp->ocount -= count;