public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Howard Chu <hyc@symas.com>
To: linux-kernel <linux-kernel@vger.kernel.org>,
	Greg KH <greg@kroah.com>, Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: [PATCH 1/2] tty: add EXTPROC support for LINEMODE
Date: Tue, 15 Jun 2010 11:10:59 -0700	[thread overview]
Message-ID: <4C17C233.2080106@symas.com> (raw)
In-Reply-To: <4C17C190.1020000@symas.com>

This adds the basic driver support. Tested on x86 and x86-64.

Signed-off-by: Howard Chu <hyc@symas.com>
---
  drivers/char/n_tty.c           |   25 ++++++++++++++++++++++---
  drivers/char/pty.c             |   13 +++++++++++++
  drivers/char/tty_ioctl.c       |   18 ++++++++++++------
  fs/compat_ioctl.c              |    1 +
  include/asm-generic/ioctls.h   |    2 ++
  include/asm-generic/termbits.h |    1 +
  include/linux/tty.h            |    1 +
  7 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index bdae832..67caa01 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1102,6 +1102,11 @@ static inline void n_tty_receive_char(struct tty_struct 
*tty, unsigned char c)
  	if (I_IUCLC(tty) && L_IEXTEN(tty))
  		c = tolower(c);

+	if (L_EXTPROC(tty)) {
+		put_tty_queue(c, tty);
+		return;
+	}
+
  	if (tty->stopped && !tty->flow_stopped && I_IXON(tty) &&
  	    I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) &&
  	    c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) {
@@ -1409,7 +1414,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, 
const unsigned char *cp,

  	n_tty_set_room(tty);

-	if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
+	if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
+		L_EXTPROC(tty)) {
  		kill_fasync(&tty->fasync, SIGIO, POLL_IN);
  		if (waitqueue_active(&tty->read_wait))
  			wake_up_interruptible(&tty->read_wait);
@@ -1585,7 +1591,7 @@ static int n_tty_open(struct tty_struct *tty)
  static inline int input_available_p(struct tty_struct *tty, int amt)
  {
  	tty_flush_to_ldisc(tty);
-	if (tty->icanon) {
+	if (tty->icanon && !L_EXTPROC(tty)) {
  		if (tty->canon_data)
  			return 1;
  	} else if (tty->read_cnt >= (amt ? amt : 1))
@@ -1632,6 +1638,11 @@ static int copy_from_read_buf(struct tty_struct *tty,
  		spin_lock_irqsave(&tty->read_lock, flags);
  		tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
  		tty->read_cnt -= n;
+		/* Check if last character is EOF */
+		if (L_EXTPROC(tty) && tty->icanon) {
+			if (!tty->read_cnt && *b[n-1] == EOF_CHAR(tty))
+				n--;
+		}
  		spin_unlock_irqrestore(&tty->read_lock, flags);
  		*b += n;
  		*nr -= n;
@@ -1767,6 +1778,14 @@ do_it_again:
  				break;
  			}
  			nr--;
+			if (cs & TIOCPKT_IOCTL) {
+				c = sizeof(struct termios);
+				if (c > nr)
+					c = nr;
+				copy_to_user(b, tty->link->termios, c);
+				nr -= c;
+				b += c;
+			}
  			break;
  		}
  		/* This statement must be first before checking for input
@@ -1812,7 +1831,7 @@ do_it_again:
  			nr--;
  		}

-		if (tty->icanon) {
+		if (tty->icanon && !L_EXTPROC(tty)) {
  			/* N.B. avoid overrun if nr == 0 */
  			while (nr && tty->read_cnt) {
  				int eol;
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index d83a431..c429e9f 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -171,6 +171,15 @@ static int pty_set_lock(struct tty_struct *tty, int 
__user *arg)
  	return 0;
  }

+/* Send a signal to the slave */
+static int pty_signal(struct tty_struct *tty, int sig)
+{
+	if (tty->link) {
+		kill_pgrp(tty->link->pgrp, sig, 1);
+	}
+	return 0;
+}
+
  static void pty_flush_buffer(struct tty_struct *tty)
  {
  	struct tty_struct *to = tty->link;
@@ -321,6 +330,8 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct 
file *file,
  	switch (cmd) {
  	case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
  		return pty_set_lock(tty, (int __user *) arg);
+	case TIOCSIG:    /* Send signal to other side of pty */
+		return pty_signal(tty, (int) arg);
  	}
  	return -ENOIOCTLCMD;
  }
@@ -476,6 +487,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct 
file *file,
  		return pty_set_lock(tty, (int __user *)arg);
  	case TIOCGPTN: /* Get PT Number */
  		return put_user(tty->index, (unsigned int __user *)arg);
+	case TIOCSIG:    /* Send signal to other side of pty */
+		return pty_signal(tty, (int) arg);
  	}

  	return -ENOIOCTLCMD;
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 6bd5f88..0c18899 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -517,19 +517,25 @@ static void change_termios(struct tty_struct *tty, 
struct ktermios *new_termios)

  	/* See if packet mode change of state. */
  	if (tty->link && tty->link->packet) {
+		int extproc = (old_termios.c_lflag & EXTPROC) |
+				(tty->termios->c_lflag & EXTPROC);
  		int old_flow = ((old_termios.c_iflag & IXON) &&
  				(old_termios.c_cc[VSTOP] == '\023') &&
  				(old_termios.c_cc[VSTART] == '\021'));
  		int new_flow = (I_IXON(tty) &&
  				STOP_CHAR(tty) == '\023' &&
  				START_CHAR(tty) == '\021');
-		if (old_flow != new_flow) {
+		if ((old_flow != new_flow) || extproc) {
  			spin_lock_irqsave(&tty->ctrl_lock, flags);
-			tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
-			if (new_flow)
-				tty->ctrl_status |= TIOCPKT_DOSTOP;
-			else
-				tty->ctrl_status |= TIOCPKT_NOSTOP;
+			if (old_flow != new_flow) {
+				tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
+				if (new_flow)
+					tty->ctrl_status |= TIOCPKT_DOSTOP;
+				else
+					tty->ctrl_status |= TIOCPKT_NOSTOP;
+			}
+			if (extproc)
+				tty->ctrl_status |= TIOCPKT_IOCTL;
  			spin_unlock_irqrestore(&tty->ctrl_lock, flags);
  			wake_up_interruptible(&tty->link->read_wait);
  		}
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 641640d..766636d 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -966,6 +966,7 @@ COMPATIBLE_IOCTL(TIOCGPGRP)
  COMPATIBLE_IOCTL(TIOCGPTN)
  COMPATIBLE_IOCTL(TIOCSPTLCK)
  COMPATIBLE_IOCTL(TIOCSERGETLSR)
+COMPATIBLE_IOCTL(TIOCSIG)
  #ifdef TCGETS2
  COMPATIBLE_IOCTL(TCGETS2)
  COMPATIBLE_IOCTL(TCSETS2)
diff --git a/include/asm-generic/ioctls.h b/include/asm-generic/ioctls.h
index a799e20..87661c8 100644
--- a/include/asm-generic/ioctls.h
+++ b/include/asm-generic/ioctls.h
@@ -69,6 +69,7 @@
  #define TCSETX		0x5433
  #define TCSETXF		0x5434
  #define TCSETXW		0x5435
+#define TIOCSIG		_IOW('T', 0x36, int)  /* pty: generate signal */

  #define FIONCLEX	0x5450
  #define FIOCLEX		0x5451
@@ -104,6 +105,7 @@
  #define TIOCPKT_START		 8
  #define TIOCPKT_NOSTOP		16
  #define TIOCPKT_DOSTOP		32
+#define TIOCPKT_IOCTL		64

  #define TIOCSER_TEMT	0x01	/* Transmitter physically empty */

diff --git a/include/asm-generic/termbits.h b/include/asm-generic/termbits.h
index 1c9773d..232b478 100644
--- a/include/asm-generic/termbits.h
+++ b/include/asm-generic/termbits.h
@@ -178,6 +178,7 @@ struct ktermios {
  #define FLUSHO	0010000
  #define PENDIN	0040000
  #define IEXTEN	0100000
+#define EXTPROC	0200000

  /* tcflow() and TCXONC use these */
  #define	TCOOFF		0
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 4409967..3cfe448 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -178,6 +178,7 @@ struct tty_bufhead {
  #define L_FLUSHO(tty)	_L_FLAG((tty), FLUSHO)
  #define L_PENDIN(tty)	_L_FLAG((tty), PENDIN)
  #define L_IEXTEN(tty)	_L_FLAG((tty), IEXTEN)
+#define L_EXTPROC(tty)	_L_FLAG((tty), EXTPROC)

  struct device;
  struct signal_struct;
-- 1.7.0.4


-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

  reply	other threads:[~2010-06-15 18:11 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-11 10:18 EXTPROC, telnetd LINEMODE, revisited Howard Chu
2010-06-11 10:41 ` Andi Kleen
2010-06-11 11:17   ` Howard Chu
2010-06-11 20:22     ` Howard Chu
2010-06-12  1:36     ` [PATCH] " Howard Chu
2010-06-15 18:08       ` [PATCH 0/2] tty: add EXTPROC support for LINEMODE Howard Chu
2010-06-15 18:10         ` Howard Chu [this message]
2010-06-15 18:13           ` [PATCH 2/2] tty: Add arch-specific EXTPROC definitions Howard Chu
2010-06-15 18:35         ` [PATCH 0/2] tty: add EXTPROC support for LINEMODE Greg KH
2010-06-15 18:46           ` Howard Chu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C17C233.2080106@symas.com \
    --to=hyc@symas.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox