Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 113442
b: refs/heads/master
c: 1d65b4a
h: refs/heads/master
v: v3
  • Loading branch information
Alan Cox authored and Linus Torvalds committed Oct 13, 2008
1 parent 8160e1e commit 3e9f529
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5aaa70a80f5bbfcc4d6a1f844bdd1c5d6b445b5f
refs/heads/master: 1d65b4a088de407e99714fdc27862449db04fb5c
58 changes: 58 additions & 0 deletions trunk/drivers/char/tty_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,50 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio)
return 0;
}


#ifdef TCGETX

/**
* set_termiox - set termiox fields if possible
* @tty: terminal
* @arg: termiox structure from user
* @opt: option flags for ioctl type
*
* Implement the device calling points for the SYS5 termiox ioctl
* interface in Linux
*/

static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
{
struct termiox tnew;
struct tty_ldisc *ld;

if (tty->termiox == NULL)
return -EINVAL;
if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
return -EFAULT;

ld = tty_ldisc_ref(tty);
if (ld != NULL) {
if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
ld->ops->flush_buffer(tty);
tty_ldisc_deref(ld);
}
if (opt & TERMIOS_WAIT) {
tty_wait_until_sent(tty, 0);
if (signal_pending(current))
return -EINTR;
}

mutex_lock(&tty->termios_mutex);
if (tty->ops->set_termiox)
tty->ops->set_termiox(tty, &tnew);
mutex_unlock(&tty->termios_mutex);
return 0;
}

#endif

static unsigned long inq_canon(struct tty_struct *tty)
{
int nr, head, tail;
Expand Down Expand Up @@ -936,6 +980,20 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
return -EFAULT;
return 0;
#endif
#ifdef TCGETX
case TCGETX:
if (real_tty->termiox == NULL)
return -EINVAL;
if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox)))
return -EFAULT;
return 0;
case TCSETX:
return set_termiox(real_tty, p, 0);
case TCSETXW:
return set_termiox(real_tty, p, TERMIOS_WAIT);
case TCSETXF:
return set_termiox(real_tty, p, TERMIOS_FLUSH);
#endif
case TIOCGSOFTCAR:
/* FIXME: for correctness we may need to take the termios
lock here - review */
Expand Down
4 changes: 4 additions & 0 deletions trunk/include/asm-x86/ioctls.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
#define TIOCGPTN _IOR('T', 0x30, unsigned int)
/* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
#define TCGETX 0x5432 /* SYS5 TCGETX compatibility */
#define TCSETX 0x5433
#define TCSETXF 0x5434
#define TCSETXW 0x5435

#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
Expand Down
15 changes: 15 additions & 0 deletions trunk/include/linux/termios.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,19 @@
#include <linux/types.h>
#include <asm/termios.h>

#define NFF 5

struct termiox
{
__u16 x_hflag;
__u16 x_cflag;
__u16 x_rflag[NFF];
__u16 x_sflag;
};

#define RTSXOFF 0x0001 /* RTS flow control on input */
#define CTSXON 0x0002 /* CTS flow control on output */
#define DTRXOFF 0x0004 /* DTR flow control on input */
#define DSRXON 0x0008 /* DCD flow control on output */

#endif
1 change: 1 addition & 0 deletions trunk/include/linux/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ struct tty_struct {
spinlock_t ctrl_lock;
/* Termios values are protected by the termios mutex */
struct ktermios *termios, *termios_locked;
struct termiox *termiox; /* May be NULL for unsupported */
char name[64];
struct pid *pgrp; /* Protected by ctrl lock */
struct pid *session;
Expand Down
9 changes: 9 additions & 0 deletions trunk/include/linux/tty_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@
* not force errors here if they are not resizable objects (eg a serial
* line). See tty_do_resize() if you need to wrap the standard method
* in your own logic - the usual case.
*
* void (*set_termiox)(struct tty_struct *tty, struct termiox *new);
*
* Called when the device receives a termiox based ioctl. Passes down
* the requested data from user space. This method will not be invoked
* unless the tty also has a valid tty->termiox pointer.
*
* Optional: Called under the termios lock
*/

#include <linux/fs.h>
Expand Down Expand Up @@ -220,6 +228,7 @@ struct tty_operations {
unsigned int set, unsigned int clear);
int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty,
struct winsize *ws);
int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
#ifdef CONFIG_CONSOLE_POLL
int (*poll_init)(struct tty_driver *driver, int line, char *options);
int (*poll_get_char)(struct tty_driver *driver, int line);
Expand Down

0 comments on commit 3e9f529

Please sign in to comment.