All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.