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/
next prev parent 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.