Skip to content

Commit

Permalink
PTY: add minimal support for TIOCPKT
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dcvmoole committed Mar 9, 2017
1 parent d7c7182 commit e6dabba
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions minix/drivers/tty/pty/pty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit e6dabba

Please sign in to comment.