diff options
Diffstat (limited to 'drivers/char/pty.c')
-rw-r--r-- | drivers/char/pty.c | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 6d4582712b1f..146c97613da0 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -5,8 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Added support for a Unix98-style ptmx device. | 6 | * Added support for a Unix98-style ptmx device. |
7 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 | 7 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 |
8 | * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to | ||
9 | * waiting writers -- Sapan Bhatia <sapan@corewars.org> | ||
10 | * | 8 | * |
11 | * When reading this code see also fs/devpts. In particular note that the | 9 | * When reading this code see also fs/devpts. In particular note that the |
12 | * driver_data field is used by the devpts side as a binding to the devpts | 10 | * driver_data field is used by the devpts side as a binding to the devpts |
@@ -34,7 +32,7 @@ | |||
34 | 32 | ||
35 | /* These are global because they are accessed in tty_io.c */ | 33 | /* These are global because they are accessed in tty_io.c */ |
36 | #ifdef CONFIG_UNIX98_PTYS | 34 | #ifdef CONFIG_UNIX98_PTYS |
37 | struct tty_driver *ptm_driver; | 35 | static struct tty_driver *ptm_driver; |
38 | static struct tty_driver *pts_driver; | 36 | static struct tty_driver *pts_driver; |
39 | #endif | 37 | #endif |
40 | 38 | ||
@@ -217,7 +215,6 @@ static int pty_open(struct tty_struct *tty, struct file *filp) | |||
217 | 215 | ||
218 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 216 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
219 | set_bit(TTY_THROTTLED, &tty->flags); | 217 | set_bit(TTY_THROTTLED, &tty->flags); |
220 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | ||
221 | retval = 0; | 218 | retval = 0; |
222 | out: | 219 | out: |
223 | return retval; | 220 | return retval; |
@@ -230,6 +227,55 @@ static void pty_set_termios(struct tty_struct *tty, | |||
230 | tty->termios->c_cflag |= (CS8 | CREAD); | 227 | tty->termios->c_cflag |= (CS8 | CREAD); |
231 | } | 228 | } |
232 | 229 | ||
230 | /** | ||
231 | * pty_do_resize - resize event | ||
232 | * @tty: tty being resized | ||
233 | * @real_tty: real tty (not the same as tty if using a pty/tty pair) | ||
234 | * @rows: rows (character) | ||
235 | * @cols: cols (character) | ||
236 | * | ||
237 | * Update the termios variables and send the neccessary signals to | ||
238 | * peform a terminal resize correctly | ||
239 | */ | ||
240 | |||
241 | int pty_resize(struct tty_struct *tty, struct winsize *ws) | ||
242 | { | ||
243 | struct pid *pgrp, *rpgrp; | ||
244 | unsigned long flags; | ||
245 | struct tty_struct *pty = tty->link; | ||
246 | |||
247 | /* For a PTY we need to lock the tty side */ | ||
248 | mutex_lock(&tty->termios_mutex); | ||
249 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) | ||
250 | goto done; | ||
251 | |||
252 | /* Get the PID values and reference them so we can | ||
253 | avoid holding the tty ctrl lock while sending signals. | ||
254 | We need to lock these individually however. */ | ||
255 | |||
256 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
257 | pgrp = get_pid(tty->pgrp); | ||
258 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
259 | |||
260 | spin_lock_irqsave(&pty->ctrl_lock, flags); | ||
261 | rpgrp = get_pid(pty->pgrp); | ||
262 | spin_unlock_irqrestore(&pty->ctrl_lock, flags); | ||
263 | |||
264 | if (pgrp) | ||
265 | kill_pgrp(pgrp, SIGWINCH, 1); | ||
266 | if (rpgrp != pgrp && rpgrp) | ||
267 | kill_pgrp(rpgrp, SIGWINCH, 1); | ||
268 | |||
269 | put_pid(pgrp); | ||
270 | put_pid(rpgrp); | ||
271 | |||
272 | tty->winsize = *ws; | ||
273 | pty->winsize = *ws; /* Never used so will go away soon */ | ||
274 | done: | ||
275 | mutex_unlock(&tty->termios_mutex); | ||
276 | return 0; | ||
277 | } | ||
278 | |||
233 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | 279 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) |
234 | { | 280 | { |
235 | struct tty_struct *o_tty; | 281 | struct tty_struct *o_tty; |
@@ -290,6 +336,7 @@ static const struct tty_operations pty_ops = { | |||
290 | .chars_in_buffer = pty_chars_in_buffer, | 336 | .chars_in_buffer = pty_chars_in_buffer, |
291 | .unthrottle = pty_unthrottle, | 337 | .unthrottle = pty_unthrottle, |
292 | .set_termios = pty_set_termios, | 338 | .set_termios = pty_set_termios, |
339 | .resize = pty_resize | ||
293 | }; | 340 | }; |
294 | 341 | ||
295 | /* Traditional BSD devices */ | 342 | /* Traditional BSD devices */ |
@@ -319,6 +366,7 @@ static const struct tty_operations pty_ops_bsd = { | |||
319 | .unthrottle = pty_unthrottle, | 366 | .unthrottle = pty_unthrottle, |
320 | .set_termios = pty_set_termios, | 367 | .set_termios = pty_set_termios, |
321 | .ioctl = pty_bsd_ioctl, | 368 | .ioctl = pty_bsd_ioctl, |
369 | .resize = pty_resize | ||
322 | }; | 370 | }; |
323 | 371 | ||
324 | static void __init legacy_pty_init(void) | 372 | static void __init legacy_pty_init(void) |
@@ -561,7 +609,8 @@ static const struct tty_operations ptm_unix98_ops = { | |||
561 | .unthrottle = pty_unthrottle, | 609 | .unthrottle = pty_unthrottle, |
562 | .set_termios = pty_set_termios, | 610 | .set_termios = pty_set_termios, |
563 | .ioctl = pty_unix98_ioctl, | 611 | .ioctl = pty_unix98_ioctl, |
564 | .shutdown = pty_unix98_shutdown | 612 | .shutdown = pty_unix98_shutdown, |
613 | .resize = pty_resize | ||
565 | }; | 614 | }; |
566 | 615 | ||
567 | static const struct tty_operations pty_unix98_ops = { | 616 | static const struct tty_operations pty_unix98_ops = { |