diff options
-rw-r--r-- | drivers/char/n_tty.c | 29 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 43 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 9 | ||||
-rw-r--r-- | include/linux/tty_ldisc.h | 7 |
4 files changed, 69 insertions, 19 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 6ac3ca4c723c..b3d4ccc33a47 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -1544,21 +1544,18 @@ static unsigned int normal_poll(struct tty_struct * tty, struct file * file, pol | |||
1544 | } | 1544 | } |
1545 | 1545 | ||
1546 | struct tty_ldisc tty_ldisc_N_TTY = { | 1546 | struct tty_ldisc tty_ldisc_N_TTY = { |
1547 | TTY_LDISC_MAGIC, /* magic */ | 1547 | .magic = TTY_LDISC_MAGIC, |
1548 | "n_tty", /* name */ | 1548 | .name = "n_tty", |
1549 | 0, /* num */ | 1549 | .open = n_tty_open, |
1550 | 0, /* flags */ | 1550 | .close = n_tty_close, |
1551 | n_tty_open, /* open */ | 1551 | .flush_buffer = n_tty_flush_buffer, |
1552 | n_tty_close, /* close */ | 1552 | .chars_in_buffer = n_tty_chars_in_buffer, |
1553 | n_tty_flush_buffer, /* flush_buffer */ | 1553 | .read = read_chan, |
1554 | n_tty_chars_in_buffer, /* chars_in_buffer */ | 1554 | .write = write_chan, |
1555 | read_chan, /* read */ | 1555 | .ioctl = n_tty_ioctl, |
1556 | write_chan, /* write */ | 1556 | .set_termios = n_tty_set_termios, |
1557 | n_tty_ioctl, /* ioctl */ | 1557 | .poll = normal_poll, |
1558 | n_tty_set_termios, /* set_termios */ | 1558 | .receive_buf = n_tty_receive_buf, |
1559 | normal_poll, /* poll */ | 1559 | .write_wakeup = n_tty_write_wakeup |
1560 | NULL, /* hangup */ | ||
1561 | n_tty_receive_buf, /* receive_buf */ | ||
1562 | n_tty_write_wakeup /* write_wakeup */ | ||
1563 | }; | 1560 | }; |
1564 | 1561 | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index fc662e4ce58a..fe62c2170d01 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -151,6 +151,12 @@ static int tty_open(struct inode *, struct file *); | |||
151 | static int tty_release(struct inode *, struct file *); | 151 | static int tty_release(struct inode *, struct file *); |
152 | int tty_ioctl(struct inode * inode, struct file * file, | 152 | int tty_ioctl(struct inode * inode, struct file * file, |
153 | unsigned int cmd, unsigned long arg); | 153 | unsigned int cmd, unsigned long arg); |
154 | #ifdef CONFIG_COMPAT | ||
155 | static long tty_compat_ioctl(struct file * file, unsigned int cmd, | ||
156 | unsigned long arg); | ||
157 | #else | ||
158 | #define tty_compat_ioctl NULL | ||
159 | #endif | ||
154 | static int tty_fasync(int fd, struct file * filp, int on); | 160 | static int tty_fasync(int fd, struct file * filp, int on); |
155 | static void release_tty(struct tty_struct *tty, int idx); | 161 | static void release_tty(struct tty_struct *tty, int idx); |
156 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); | 162 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
@@ -1143,8 +1149,8 @@ static unsigned int hung_up_tty_poll(struct file * filp, poll_table * wait) | |||
1143 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; | 1149 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; |
1144 | } | 1150 | } |
1145 | 1151 | ||
1146 | static int hung_up_tty_ioctl(struct inode * inode, struct file * file, | 1152 | static long hung_up_tty_ioctl(struct file * file, |
1147 | unsigned int cmd, unsigned long arg) | 1153 | unsigned int cmd, unsigned long arg) |
1148 | { | 1154 | { |
1149 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | 1155 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; |
1150 | } | 1156 | } |
@@ -1155,6 +1161,7 @@ static const struct file_operations tty_fops = { | |||
1155 | .write = tty_write, | 1161 | .write = tty_write, |
1156 | .poll = tty_poll, | 1162 | .poll = tty_poll, |
1157 | .ioctl = tty_ioctl, | 1163 | .ioctl = tty_ioctl, |
1164 | .compat_ioctl = tty_compat_ioctl, | ||
1158 | .open = tty_open, | 1165 | .open = tty_open, |
1159 | .release = tty_release, | 1166 | .release = tty_release, |
1160 | .fasync = tty_fasync, | 1167 | .fasync = tty_fasync, |
@@ -1167,6 +1174,7 @@ static const struct file_operations ptmx_fops = { | |||
1167 | .write = tty_write, | 1174 | .write = tty_write, |
1168 | .poll = tty_poll, | 1175 | .poll = tty_poll, |
1169 | .ioctl = tty_ioctl, | 1176 | .ioctl = tty_ioctl, |
1177 | .compat_ioctl = tty_compat_ioctl, | ||
1170 | .open = ptmx_open, | 1178 | .open = ptmx_open, |
1171 | .release = tty_release, | 1179 | .release = tty_release, |
1172 | .fasync = tty_fasync, | 1180 | .fasync = tty_fasync, |
@@ -1179,6 +1187,7 @@ static const struct file_operations console_fops = { | |||
1179 | .write = redirected_tty_write, | 1187 | .write = redirected_tty_write, |
1180 | .poll = tty_poll, | 1188 | .poll = tty_poll, |
1181 | .ioctl = tty_ioctl, | 1189 | .ioctl = tty_ioctl, |
1190 | .compat_ioctl = tty_compat_ioctl, | ||
1182 | .open = tty_open, | 1191 | .open = tty_open, |
1183 | .release = tty_release, | 1192 | .release = tty_release, |
1184 | .fasync = tty_fasync, | 1193 | .fasync = tty_fasync, |
@@ -1189,7 +1198,8 @@ static const struct file_operations hung_up_tty_fops = { | |||
1189 | .read = hung_up_tty_read, | 1198 | .read = hung_up_tty_read, |
1190 | .write = hung_up_tty_write, | 1199 | .write = hung_up_tty_write, |
1191 | .poll = hung_up_tty_poll, | 1200 | .poll = hung_up_tty_poll, |
1192 | .ioctl = hung_up_tty_ioctl, | 1201 | .unlocked_ioctl = hung_up_tty_ioctl, |
1202 | .compat_ioctl = hung_up_tty_ioctl, | ||
1193 | .release = tty_release, | 1203 | .release = tty_release, |
1194 | }; | 1204 | }; |
1195 | 1205 | ||
@@ -3357,6 +3367,32 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
3357 | return retval; | 3367 | return retval; |
3358 | } | 3368 | } |
3359 | 3369 | ||
3370 | #ifdef CONFIG_COMPAT | ||
3371 | static long tty_compat_ioctl(struct file * file, unsigned int cmd, | ||
3372 | unsigned long arg) | ||
3373 | { | ||
3374 | struct inode *inode = file->f_dentry->d_inode; | ||
3375 | struct tty_struct *tty = file->private_data; | ||
3376 | struct tty_ldisc *ld; | ||
3377 | int retval = -ENOIOCTLCMD; | ||
3378 | |||
3379 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) | ||
3380 | return -EINVAL; | ||
3381 | |||
3382 | if (tty->driver->compat_ioctl) { | ||
3383 | retval = (tty->driver->compat_ioctl)(tty, file, cmd, arg); | ||
3384 | if (retval != -ENOIOCTLCMD) | ||
3385 | return retval; | ||
3386 | } | ||
3387 | |||
3388 | ld = tty_ldisc_ref_wait(tty); | ||
3389 | if (ld->compat_ioctl) | ||
3390 | retval = ld->compat_ioctl(tty, file, cmd, arg); | ||
3391 | tty_ldisc_deref(ld); | ||
3392 | |||
3393 | return retval; | ||
3394 | } | ||
3395 | #endif | ||
3360 | 3396 | ||
3361 | /* | 3397 | /* |
3362 | * This implements the "Secure Attention Key" --- the idea is to | 3398 | * This implements the "Secure Attention Key" --- the idea is to |
@@ -3689,6 +3725,7 @@ void tty_set_operations(struct tty_driver *driver, | |||
3689 | driver->write_room = op->write_room; | 3725 | driver->write_room = op->write_room; |
3690 | driver->chars_in_buffer = op->chars_in_buffer; | 3726 | driver->chars_in_buffer = op->chars_in_buffer; |
3691 | driver->ioctl = op->ioctl; | 3727 | driver->ioctl = op->ioctl; |
3728 | driver->compat_ioctl = op->compat_ioctl; | ||
3692 | driver->set_termios = op->set_termios; | 3729 | driver->set_termios = op->set_termios; |
3693 | driver->throttle = op->throttle; | 3730 | driver->throttle = op->throttle; |
3694 | driver->unthrottle = op->unthrottle; | 3731 | driver->unthrottle = op->unthrottle; |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 659487e3ebeb..85c95cd39bc3 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
@@ -52,6 +52,11 @@ | |||
52 | * This routine allows the tty driver to implement | 52 | * This routine allows the tty driver to implement |
53 | * device-specific ioctl's. If the ioctl number passed in cmd | 53 | * device-specific ioctl's. If the ioctl number passed in cmd |
54 | * is not recognized by the driver, it should return ENOIOCTLCMD. | 54 | * is not recognized by the driver, it should return ENOIOCTLCMD. |
55 | * | ||
56 | * long (*compat_ioctl)(struct tty_struct *tty, struct file * file, | ||
57 | * unsigned int cmd, unsigned long arg); | ||
58 | * | ||
59 | * implement ioctl processing for 32 bit process on 64 bit system | ||
55 | * | 60 | * |
56 | * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); | 61 | * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); |
57 | * | 62 | * |
@@ -132,6 +137,8 @@ struct tty_operations { | |||
132 | int (*chars_in_buffer)(struct tty_struct *tty); | 137 | int (*chars_in_buffer)(struct tty_struct *tty); |
133 | int (*ioctl)(struct tty_struct *tty, struct file * file, | 138 | int (*ioctl)(struct tty_struct *tty, struct file * file, |
134 | unsigned int cmd, unsigned long arg); | 139 | unsigned int cmd, unsigned long arg); |
140 | long (*compat_ioctl)(struct tty_struct *tty, struct file * file, | ||
141 | unsigned int cmd, unsigned long arg); | ||
135 | void (*set_termios)(struct tty_struct *tty, struct ktermios * old); | 142 | void (*set_termios)(struct tty_struct *tty, struct ktermios * old); |
136 | void (*throttle)(struct tty_struct * tty); | 143 | void (*throttle)(struct tty_struct * tty); |
137 | void (*unthrottle)(struct tty_struct * tty); | 144 | void (*unthrottle)(struct tty_struct * tty); |
@@ -193,6 +200,8 @@ struct tty_driver { | |||
193 | int (*chars_in_buffer)(struct tty_struct *tty); | 200 | int (*chars_in_buffer)(struct tty_struct *tty); |
194 | int (*ioctl)(struct tty_struct *tty, struct file * file, | 201 | int (*ioctl)(struct tty_struct *tty, struct file * file, |
195 | unsigned int cmd, unsigned long arg); | 202 | unsigned int cmd, unsigned long arg); |
203 | long (*compat_ioctl)(struct tty_struct *tty, struct file * file, | ||
204 | unsigned int cmd, unsigned long arg); | ||
196 | void (*set_termios)(struct tty_struct *tty, struct ktermios * old); | 205 | void (*set_termios)(struct tty_struct *tty, struct ktermios * old); |
197 | void (*throttle)(struct tty_struct * tty); | 206 | void (*throttle)(struct tty_struct * tty); |
198 | void (*unthrottle)(struct tty_struct * tty); | 207 | void (*unthrottle)(struct tty_struct * tty); |
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index d75932e27710..6226504d9108 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h | |||
@@ -59,6 +59,11 @@ | |||
59 | * low-level driver can "grab" an ioctl request before the line | 59 | * low-level driver can "grab" an ioctl request before the line |
60 | * discpline has a chance to see it. | 60 | * discpline has a chance to see it. |
61 | * | 61 | * |
62 | * long (*compat_ioctl)(struct tty_struct * tty, struct file * file, | ||
63 | * unsigned int cmd, unsigned long arg); | ||
64 | * | ||
65 | * Process ioctl calls from 32-bit process on 64-bit system | ||
66 | * | ||
62 | * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); | 67 | * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); |
63 | * | 68 | * |
64 | * This function notifies the line discpline that a change has | 69 | * This function notifies the line discpline that a change has |
@@ -118,6 +123,8 @@ struct tty_ldisc { | |||
118 | const unsigned char * buf, size_t nr); | 123 | const unsigned char * buf, size_t nr); |
119 | int (*ioctl)(struct tty_struct * tty, struct file * file, | 124 | int (*ioctl)(struct tty_struct * tty, struct file * file, |
120 | unsigned int cmd, unsigned long arg); | 125 | unsigned int cmd, unsigned long arg); |
126 | long (*compat_ioctl)(struct tty_struct * tty, struct file * file, | ||
127 | unsigned int cmd, unsigned long arg); | ||
121 | void (*set_termios)(struct tty_struct *tty, struct ktermios * old); | 128 | void (*set_termios)(struct tty_struct *tty, struct ktermios * old); |
122 | unsigned int (*poll)(struct tty_struct *, struct file *, | 129 | unsigned int (*poll)(struct tty_struct *, struct file *, |
123 | struct poll_table_struct *); | 130 | struct poll_table_struct *); |