diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2006-08-27 04:24:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-27 14:01:34 -0400 |
commit | af9b897ee639d96b2bd29b65b50cd0a1f2b6d6c9 (patch) | |
tree | 6b97baedcaefb7ab84eaecb9b4d6a9d4ea25369f /drivers | |
parent | 9c275a8391d96b49fa135d1e4073d4798b7c6445 (diff) |
[PATCH] tty layer comment the locking assumptions and functions somewhat
Doesn't fix them but does show up some interesting areas that need review
and fixing.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/tty_io.c | 718 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 59 |
2 files changed, 715 insertions, 62 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index d6e4eaa48538..2cef982585f0 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -153,6 +153,15 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
153 | static int tty_fasync(int fd, struct file * filp, int on); | 153 | static int tty_fasync(int fd, struct file * filp, int on); |
154 | static void release_mem(struct tty_struct *tty, int idx); | 154 | static void release_mem(struct tty_struct *tty, int idx); |
155 | 155 | ||
156 | /** | ||
157 | * alloc_tty_struct - allocate a tty object | ||
158 | * | ||
159 | * Return a new empty tty structure. The data fields have not | ||
160 | * been initialized in any way but has been zeroed | ||
161 | * | ||
162 | * Locking: none | ||
163 | * FIXME: use kzalloc | ||
164 | */ | ||
156 | 165 | ||
157 | static struct tty_struct *alloc_tty_struct(void) | 166 | static struct tty_struct *alloc_tty_struct(void) |
158 | { | 167 | { |
@@ -166,6 +175,15 @@ static struct tty_struct *alloc_tty_struct(void) | |||
166 | 175 | ||
167 | static void tty_buffer_free_all(struct tty_struct *); | 176 | static void tty_buffer_free_all(struct tty_struct *); |
168 | 177 | ||
178 | /** | ||
179 | * free_tty_struct - free a disused tty | ||
180 | * @tty: tty struct to free | ||
181 | * | ||
182 | * Free the write buffers, tty queue and tty memory itself. | ||
183 | * | ||
184 | * Locking: none. Must be called after tty is definitely unused | ||
185 | */ | ||
186 | |||
169 | static inline void free_tty_struct(struct tty_struct *tty) | 187 | static inline void free_tty_struct(struct tty_struct *tty) |
170 | { | 188 | { |
171 | kfree(tty->write_buf); | 189 | kfree(tty->write_buf); |
@@ -175,6 +193,17 @@ static inline void free_tty_struct(struct tty_struct *tty) | |||
175 | 193 | ||
176 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) | 194 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) |
177 | 195 | ||
196 | /** | ||
197 | * tty_name - return tty naming | ||
198 | * @tty: tty structure | ||
199 | * @buf: buffer for output | ||
200 | * | ||
201 | * Convert a tty structure into a name. The name reflects the kernel | ||
202 | * naming policy and if udev is in use may not reflect user space | ||
203 | * | ||
204 | * Locking: none | ||
205 | */ | ||
206 | |||
178 | char *tty_name(struct tty_struct *tty, char *buf) | 207 | char *tty_name(struct tty_struct *tty, char *buf) |
179 | { | 208 | { |
180 | if (!tty) /* Hmm. NULL pointer. That's fun. */ | 209 | if (!tty) /* Hmm. NULL pointer. That's fun. */ |
@@ -235,6 +264,17 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
235 | * Tty buffer allocation management | 264 | * Tty buffer allocation management |
236 | */ | 265 | */ |
237 | 266 | ||
267 | |||
268 | /** | ||
269 | * tty_buffer_free_all - free buffers used by a tty | ||
270 | * @tty: tty to free from | ||
271 | * | ||
272 | * Remove all the buffers pending on a tty whether queued with data | ||
273 | * or in the free ring. Must be called when the tty is no longer in use | ||
274 | * | ||
275 | * Locking: none | ||
276 | */ | ||
277 | |||
238 | static void tty_buffer_free_all(struct tty_struct *tty) | 278 | static void tty_buffer_free_all(struct tty_struct *tty) |
239 | { | 279 | { |
240 | struct tty_buffer *thead; | 280 | struct tty_buffer *thead; |
@@ -347,6 +387,18 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
347 | } | 387 | } |
348 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 388 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
349 | 389 | ||
390 | /** | ||
391 | * tty_insert_flip_string - Add characters to the tty buffer | ||
392 | * @tty: tty structure | ||
393 | * @chars: characters | ||
394 | * @size: size | ||
395 | * | ||
396 | * Queue a series of bytes to the tty buffering. All the characters | ||
397 | * passed are marked as without error. Returns the number added. | ||
398 | * | ||
399 | * Locking: Called functions may take tty->buf.lock | ||
400 | */ | ||
401 | |||
350 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | 402 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, |
351 | size_t size) | 403 | size_t size) |
352 | { | 404 | { |
@@ -370,6 +422,20 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | |||
370 | } | 422 | } |
371 | EXPORT_SYMBOL(tty_insert_flip_string); | 423 | EXPORT_SYMBOL(tty_insert_flip_string); |
372 | 424 | ||
425 | /** | ||
426 | * tty_insert_flip_string_flags - Add characters to the tty buffer | ||
427 | * @tty: tty structure | ||
428 | * @chars: characters | ||
429 | * @flags: flag bytes | ||
430 | * @size: size | ||
431 | * | ||
432 | * Queue a series of bytes to the tty buffering. For each character | ||
433 | * the flags array indicates the status of the character. Returns the | ||
434 | * number added. | ||
435 | * | ||
436 | * Locking: Called functions may take tty->buf.lock | ||
437 | */ | ||
438 | |||
373 | int tty_insert_flip_string_flags(struct tty_struct *tty, | 439 | int tty_insert_flip_string_flags(struct tty_struct *tty, |
374 | const unsigned char *chars, const char *flags, size_t size) | 440 | const unsigned char *chars, const char *flags, size_t size) |
375 | { | 441 | { |
@@ -394,6 +460,17 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, | |||
394 | } | 460 | } |
395 | EXPORT_SYMBOL(tty_insert_flip_string_flags); | 461 | EXPORT_SYMBOL(tty_insert_flip_string_flags); |
396 | 462 | ||
463 | /** | ||
464 | * tty_schedule_flip - push characters to ldisc | ||
465 | * @tty: tty to push from | ||
466 | * | ||
467 | * Takes any pending buffers and transfers their ownership to the | ||
468 | * ldisc side of the queue. It then schedules those characters for | ||
469 | * processing by the line discipline. | ||
470 | * | ||
471 | * Locking: Takes tty->buf.lock | ||
472 | */ | ||
473 | |||
397 | void tty_schedule_flip(struct tty_struct *tty) | 474 | void tty_schedule_flip(struct tty_struct *tty) |
398 | { | 475 | { |
399 | unsigned long flags; | 476 | unsigned long flags; |
@@ -405,12 +482,19 @@ void tty_schedule_flip(struct tty_struct *tty) | |||
405 | } | 482 | } |
406 | EXPORT_SYMBOL(tty_schedule_flip); | 483 | EXPORT_SYMBOL(tty_schedule_flip); |
407 | 484 | ||
408 | /* | 485 | /** |
486 | * tty_prepare_flip_string - make room for characters | ||
487 | * @tty: tty | ||
488 | * @chars: return pointer for character write area | ||
489 | * @size: desired size | ||
490 | * | ||
409 | * Prepare a block of space in the buffer for data. Returns the length | 491 | * Prepare a block of space in the buffer for data. Returns the length |
410 | * available and buffer pointer to the space which is now allocated and | 492 | * available and buffer pointer to the space which is now allocated and |
411 | * accounted for as ready for normal characters. This is used for drivers | 493 | * accounted for as ready for normal characters. This is used for drivers |
412 | * that need their own block copy routines into the buffer. There is no | 494 | * that need their own block copy routines into the buffer. There is no |
413 | * guarantee the buffer is a DMA target! | 495 | * guarantee the buffer is a DMA target! |
496 | * | ||
497 | * Locking: May call functions taking tty->buf.lock | ||
414 | */ | 498 | */ |
415 | 499 | ||
416 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) | 500 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) |
@@ -427,12 +511,20 @@ int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_ | |||
427 | 511 | ||
428 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | 512 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); |
429 | 513 | ||
430 | /* | 514 | /** |
515 | * tty_prepare_flip_string_flags - make room for characters | ||
516 | * @tty: tty | ||
517 | * @chars: return pointer for character write area | ||
518 | * @flags: return pointer for status flag write area | ||
519 | * @size: desired size | ||
520 | * | ||
431 | * Prepare a block of space in the buffer for data. Returns the length | 521 | * Prepare a block of space in the buffer for data. Returns the length |
432 | * available and buffer pointer to the space which is now allocated and | 522 | * available and buffer pointer to the space which is now allocated and |
433 | * accounted for as ready for characters. This is used for drivers | 523 | * accounted for as ready for characters. This is used for drivers |
434 | * that need their own block copy routines into the buffer. There is no | 524 | * that need their own block copy routines into the buffer. There is no |
435 | * guarantee the buffer is a DMA target! | 525 | * guarantee the buffer is a DMA target! |
526 | * | ||
527 | * Locking: May call functions taking tty->buf.lock | ||
436 | */ | 528 | */ |
437 | 529 | ||
438 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) | 530 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) |
@@ -451,10 +543,16 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | |||
451 | 543 | ||
452 | 544 | ||
453 | 545 | ||
454 | /* | 546 | /** |
547 | * tty_set_termios_ldisc - set ldisc field | ||
548 | * @tty: tty structure | ||
549 | * @num: line discipline number | ||
550 | * | ||
455 | * This is probably overkill for real world processors but | 551 | * This is probably overkill for real world processors but |
456 | * they are not on hot paths so a little discipline won't do | 552 | * they are not on hot paths so a little discipline won't do |
457 | * any harm. | 553 | * any harm. |
554 | * | ||
555 | * Locking: takes termios_sem | ||
458 | */ | 556 | */ |
459 | 557 | ||
460 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 558 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) |
@@ -474,6 +572,19 @@ static DEFINE_SPINLOCK(tty_ldisc_lock); | |||
474 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | 572 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); |
475 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ | 573 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ |
476 | 574 | ||
575 | /** | ||
576 | * tty_register_ldisc - install a line discipline | ||
577 | * @disc: ldisc number | ||
578 | * @new_ldisc: pointer to the ldisc object | ||
579 | * | ||
580 | * Installs a new line discipline into the kernel. The discipline | ||
581 | * is set up as unreferenced and then made available to the kernel | ||
582 | * from this point onwards. | ||
583 | * | ||
584 | * Locking: | ||
585 | * takes tty_ldisc_lock to guard against ldisc races | ||
586 | */ | ||
587 | |||
477 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | 588 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) |
478 | { | 589 | { |
479 | unsigned long flags; | 590 | unsigned long flags; |
@@ -493,6 +604,18 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | |||
493 | } | 604 | } |
494 | EXPORT_SYMBOL(tty_register_ldisc); | 605 | EXPORT_SYMBOL(tty_register_ldisc); |
495 | 606 | ||
607 | /** | ||
608 | * tty_unregister_ldisc - unload a line discipline | ||
609 | * @disc: ldisc number | ||
610 | * @new_ldisc: pointer to the ldisc object | ||
611 | * | ||
612 | * Remove a line discipline from the kernel providing it is not | ||
613 | * currently in use. | ||
614 | * | ||
615 | * Locking: | ||
616 | * takes tty_ldisc_lock to guard against ldisc races | ||
617 | */ | ||
618 | |||
496 | int tty_unregister_ldisc(int disc) | 619 | int tty_unregister_ldisc(int disc) |
497 | { | 620 | { |
498 | unsigned long flags; | 621 | unsigned long flags; |
@@ -512,6 +635,19 @@ int tty_unregister_ldisc(int disc) | |||
512 | } | 635 | } |
513 | EXPORT_SYMBOL(tty_unregister_ldisc); | 636 | EXPORT_SYMBOL(tty_unregister_ldisc); |
514 | 637 | ||
638 | /** | ||
639 | * tty_ldisc_get - take a reference to an ldisc | ||
640 | * @disc: ldisc number | ||
641 | * | ||
642 | * Takes a reference to a line discipline. Deals with refcounts and | ||
643 | * module locking counts. Returns NULL if the discipline is not available. | ||
644 | * Returns a pointer to the discipline and bumps the ref count if it is | ||
645 | * available | ||
646 | * | ||
647 | * Locking: | ||
648 | * takes tty_ldisc_lock to guard against ldisc races | ||
649 | */ | ||
650 | |||
515 | struct tty_ldisc *tty_ldisc_get(int disc) | 651 | struct tty_ldisc *tty_ldisc_get(int disc) |
516 | { | 652 | { |
517 | unsigned long flags; | 653 | unsigned long flags; |
@@ -540,6 +676,17 @@ struct tty_ldisc *tty_ldisc_get(int disc) | |||
540 | 676 | ||
541 | EXPORT_SYMBOL_GPL(tty_ldisc_get); | 677 | EXPORT_SYMBOL_GPL(tty_ldisc_get); |
542 | 678 | ||
679 | /** | ||
680 | * tty_ldisc_put - drop ldisc reference | ||
681 | * @disc: ldisc number | ||
682 | * | ||
683 | * Drop a reference to a line discipline. Manage refcounts and | ||
684 | * module usage counts | ||
685 | * | ||
686 | * Locking: | ||
687 | * takes tty_ldisc_lock to guard against ldisc races | ||
688 | */ | ||
689 | |||
543 | void tty_ldisc_put(int disc) | 690 | void tty_ldisc_put(int disc) |
544 | { | 691 | { |
545 | struct tty_ldisc *ld; | 692 | struct tty_ldisc *ld; |
@@ -557,6 +704,19 @@ void tty_ldisc_put(int disc) | |||
557 | 704 | ||
558 | EXPORT_SYMBOL_GPL(tty_ldisc_put); | 705 | EXPORT_SYMBOL_GPL(tty_ldisc_put); |
559 | 706 | ||
707 | /** | ||
708 | * tty_ldisc_assign - set ldisc on a tty | ||
709 | * @tty: tty to assign | ||
710 | * @ld: line discipline | ||
711 | * | ||
712 | * Install an instance of a line discipline into a tty structure. The | ||
713 | * ldisc must have a reference count above zero to ensure it remains/ | ||
714 | * The tty instance refcount starts at zero. | ||
715 | * | ||
716 | * Locking: | ||
717 | * Caller must hold references | ||
718 | */ | ||
719 | |||
560 | static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) | 720 | static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) |
561 | { | 721 | { |
562 | tty->ldisc = *ld; | 722 | tty->ldisc = *ld; |
@@ -571,6 +731,8 @@ static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) | |||
571 | * the tty ldisc. Return 0 on failure or 1 on success. This is | 731 | * the tty ldisc. Return 0 on failure or 1 on success. This is |
572 | * used to implement both the waiting and non waiting versions | 732 | * used to implement both the waiting and non waiting versions |
573 | * of tty_ldisc_ref | 733 | * of tty_ldisc_ref |
734 | * | ||
735 | * Locking: takes tty_ldisc_lock | ||
574 | */ | 736 | */ |
575 | 737 | ||
576 | static int tty_ldisc_try(struct tty_struct *tty) | 738 | static int tty_ldisc_try(struct tty_struct *tty) |
@@ -602,6 +764,8 @@ static int tty_ldisc_try(struct tty_struct *tty) | |||
602 | * must also be careful not to hold other locks that will deadlock | 764 | * must also be careful not to hold other locks that will deadlock |
603 | * against a discipline change, such as an existing ldisc reference | 765 | * against a discipline change, such as an existing ldisc reference |
604 | * (which we check for) | 766 | * (which we check for) |
767 | * | ||
768 | * Locking: call functions take tty_ldisc_lock | ||
605 | */ | 769 | */ |
606 | 770 | ||
607 | struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) | 771 | struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) |
@@ -622,6 +786,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); | |||
622 | * Dereference the line discipline for the terminal and take a | 786 | * Dereference the line discipline for the terminal and take a |
623 | * reference to it. If the line discipline is in flux then | 787 | * reference to it. If the line discipline is in flux then |
624 | * return NULL. Can be called from IRQ and timer functions. | 788 | * return NULL. Can be called from IRQ and timer functions. |
789 | * | ||
790 | * Locking: called functions take tty_ldisc_lock | ||
625 | */ | 791 | */ |
626 | 792 | ||
627 | struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) | 793 | struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) |
@@ -639,6 +805,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref); | |||
639 | * | 805 | * |
640 | * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May | 806 | * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May |
641 | * be called in IRQ context. | 807 | * be called in IRQ context. |
808 | * | ||
809 | * Locking: takes tty_ldisc_lock | ||
642 | */ | 810 | */ |
643 | 811 | ||
644 | void tty_ldisc_deref(struct tty_ldisc *ld) | 812 | void tty_ldisc_deref(struct tty_ldisc *ld) |
@@ -683,6 +851,9 @@ static void tty_ldisc_enable(struct tty_struct *tty) | |||
683 | * | 851 | * |
684 | * Set the discipline of a tty line. Must be called from a process | 852 | * Set the discipline of a tty line. Must be called from a process |
685 | * context. | 853 | * context. |
854 | * | ||
855 | * Locking: takes tty_ldisc_lock. | ||
856 | * called functions take termios_sem | ||
686 | */ | 857 | */ |
687 | 858 | ||
688 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) | 859 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) |
@@ -846,9 +1017,17 @@ restart: | |||
846 | return retval; | 1017 | return retval; |
847 | } | 1018 | } |
848 | 1019 | ||
849 | /* | 1020 | /** |
850 | * This routine returns a tty driver structure, given a device number | 1021 | * get_tty_driver - find device of a tty |
1022 | * @dev_t: device identifier | ||
1023 | * @index: returns the index of the tty | ||
1024 | * | ||
1025 | * This routine returns a tty driver structure, given a device number | ||
1026 | * and also passes back the index number. | ||
1027 | * | ||
1028 | * Locking: caller must hold tty_mutex | ||
851 | */ | 1029 | */ |
1030 | |||
852 | static struct tty_driver *get_tty_driver(dev_t device, int *index) | 1031 | static struct tty_driver *get_tty_driver(dev_t device, int *index) |
853 | { | 1032 | { |
854 | struct tty_driver *p; | 1033 | struct tty_driver *p; |
@@ -863,11 +1042,17 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) | |||
863 | return NULL; | 1042 | return NULL; |
864 | } | 1043 | } |
865 | 1044 | ||
866 | /* | 1045 | /** |
867 | * If we try to write to, or set the state of, a terminal and we're | 1046 | * tty_check_change - check for POSIX terminal changes |
868 | * not in the foreground, send a SIGTTOU. If the signal is blocked or | 1047 | * @tty: tty to check |
869 | * ignored, go ahead and perform the operation. (POSIX 7.2) | 1048 | * |
1049 | * If we try to write to, or set the state of, a terminal and we're | ||
1050 | * not in the foreground, send a SIGTTOU. If the signal is blocked or | ||
1051 | * ignored, go ahead and perform the operation. (POSIX 7.2) | ||
1052 | * | ||
1053 | * Locking: none | ||
870 | */ | 1054 | */ |
1055 | |||
871 | int tty_check_change(struct tty_struct * tty) | 1056 | int tty_check_change(struct tty_struct * tty) |
872 | { | 1057 | { |
873 | if (current->signal->tty != tty) | 1058 | if (current->signal->tty != tty) |
@@ -1005,10 +1190,27 @@ void tty_ldisc_flush(struct tty_struct *tty) | |||
1005 | 1190 | ||
1006 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); | 1191 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
1007 | 1192 | ||
1008 | /* | 1193 | /** |
1009 | * This can be called by the "eventd" kernel thread. That is process synchronous, | 1194 | * do_tty_hangup - actual handler for hangup events |
1010 | * but doesn't hold any locks, so we need to make sure we have the appropriate | 1195 | * @data: tty device |
1011 | * locks for what we're doing.. | 1196 | * |
1197 | * This can be called by the "eventd" kernel thread. That is process | ||
1198 | * synchronous but doesn't hold any locks, so we need to make sure we | ||
1199 | * have the appropriate locks for what we're doing. | ||
1200 | * | ||
1201 | * The hangup event clears any pending redirections onto the hung up | ||
1202 | * device. It ensures future writes will error and it does the needed | ||
1203 | * line discipline hangup and signal delivery. The tty object itself | ||
1204 | * remains intact. | ||
1205 | * | ||
1206 | * Locking: | ||
1207 | * BKL | ||
1208 | * redirect lock for undoing redirection | ||
1209 | * file list lock for manipulating list of ttys | ||
1210 | * tty_ldisc_lock from called functions | ||
1211 | * termios_sem resetting termios data | ||
1212 | * tasklist_lock to walk task list for hangup event | ||
1213 | * | ||
1012 | */ | 1214 | */ |
1013 | static void do_tty_hangup(void *data) | 1215 | static void do_tty_hangup(void *data) |
1014 | { | 1216 | { |
@@ -1133,6 +1335,14 @@ static void do_tty_hangup(void *data) | |||
1133 | fput(f); | 1335 | fput(f); |
1134 | } | 1336 | } |
1135 | 1337 | ||
1338 | /** | ||
1339 | * tty_hangup - trigger a hangup event | ||
1340 | * @tty: tty to hangup | ||
1341 | * | ||
1342 | * A carrier loss (virtual or otherwise) has occurred on this like | ||
1343 | * schedule a hangup sequence to run after this event. | ||
1344 | */ | ||
1345 | |||
1136 | void tty_hangup(struct tty_struct * tty) | 1346 | void tty_hangup(struct tty_struct * tty) |
1137 | { | 1347 | { |
1138 | #ifdef TTY_DEBUG_HANGUP | 1348 | #ifdef TTY_DEBUG_HANGUP |
@@ -1145,6 +1355,15 @@ void tty_hangup(struct tty_struct * tty) | |||
1145 | 1355 | ||
1146 | EXPORT_SYMBOL(tty_hangup); | 1356 | EXPORT_SYMBOL(tty_hangup); |
1147 | 1357 | ||
1358 | /** | ||
1359 | * tty_vhangup - process vhangup | ||
1360 | * @tty: tty to hangup | ||
1361 | * | ||
1362 | * The user has asked via system call for the terminal to be hung up. | ||
1363 | * We do this synchronously so that when the syscall returns the process | ||
1364 | * is complete. That guarantee is neccessary for security reasons. | ||
1365 | */ | ||
1366 | |||
1148 | void tty_vhangup(struct tty_struct * tty) | 1367 | void tty_vhangup(struct tty_struct * tty) |
1149 | { | 1368 | { |
1150 | #ifdef TTY_DEBUG_HANGUP | 1369 | #ifdef TTY_DEBUG_HANGUP |
@@ -1156,6 +1375,14 @@ void tty_vhangup(struct tty_struct * tty) | |||
1156 | } | 1375 | } |
1157 | EXPORT_SYMBOL(tty_vhangup); | 1376 | EXPORT_SYMBOL(tty_vhangup); |
1158 | 1377 | ||
1378 | /** | ||
1379 | * tty_hung_up_p - was tty hung up | ||
1380 | * @filp: file pointer of tty | ||
1381 | * | ||
1382 | * Return true if the tty has been subject to a vhangup or a carrier | ||
1383 | * loss | ||
1384 | */ | ||
1385 | |||
1159 | int tty_hung_up_p(struct file * filp) | 1386 | int tty_hung_up_p(struct file * filp) |
1160 | { | 1387 | { |
1161 | return (filp->f_op == &hung_up_tty_fops); | 1388 | return (filp->f_op == &hung_up_tty_fops); |
@@ -1163,19 +1390,28 @@ int tty_hung_up_p(struct file * filp) | |||
1163 | 1390 | ||
1164 | EXPORT_SYMBOL(tty_hung_up_p); | 1391 | EXPORT_SYMBOL(tty_hung_up_p); |
1165 | 1392 | ||
1166 | /* | 1393 | /** |
1167 | * This function is typically called only by the session leader, when | 1394 | * disassociate_ctty - disconnect controlling tty |
1168 | * it wants to disassociate itself from its controlling tty. | 1395 | * @on_exit: true if exiting so need to "hang up" the session |
1169 | * | 1396 | * |
1170 | * It performs the following functions: | 1397 | * This function is typically called only by the session leader, when |
1398 | * it wants to disassociate itself from its controlling tty. | ||
1399 | * | ||
1400 | * It performs the following functions: | ||
1171 | * (1) Sends a SIGHUP and SIGCONT to the foreground process group | 1401 | * (1) Sends a SIGHUP and SIGCONT to the foreground process group |
1172 | * (2) Clears the tty from being controlling the session | 1402 | * (2) Clears the tty from being controlling the session |
1173 | * (3) Clears the controlling tty for all processes in the | 1403 | * (3) Clears the controlling tty for all processes in the |
1174 | * session group. | 1404 | * session group. |
1175 | * | 1405 | * |
1176 | * The argument on_exit is set to 1 if called when a process is | 1406 | * The argument on_exit is set to 1 if called when a process is |
1177 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 1407 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
1408 | * | ||
1409 | * Locking: tty_mutex is taken to protect current->signal->tty | ||
1410 | * BKL is taken for hysterical raisins | ||
1411 | * Tasklist lock is taken (under tty_mutex) to walk process | ||
1412 | * lists for the session. | ||
1178 | */ | 1413 | */ |
1414 | |||
1179 | void disassociate_ctty(int on_exit) | 1415 | void disassociate_ctty(int on_exit) |
1180 | { | 1416 | { |
1181 | struct tty_struct *tty; | 1417 | struct tty_struct *tty; |
@@ -1222,6 +1458,25 @@ void disassociate_ctty(int on_exit) | |||
1222 | unlock_kernel(); | 1458 | unlock_kernel(); |
1223 | } | 1459 | } |
1224 | 1460 | ||
1461 | |||
1462 | /** | ||
1463 | * stop_tty - propogate flow control | ||
1464 | * @tty: tty to stop | ||
1465 | * | ||
1466 | * Perform flow control to the driver. For PTY/TTY pairs we | ||
1467 | * must also propogate the TIOCKPKT status. May be called | ||
1468 | * on an already stopped device and will not re-call the driver | ||
1469 | * method. | ||
1470 | * | ||
1471 | * This functionality is used by both the line disciplines for | ||
1472 | * halting incoming flow and by the driver. It may therefore be | ||
1473 | * called from any context, may be under the tty atomic_write_lock | ||
1474 | * but not always. | ||
1475 | * | ||
1476 | * Locking: | ||
1477 | * Broken. Relies on BKL which is unsafe here. | ||
1478 | */ | ||
1479 | |||
1225 | void stop_tty(struct tty_struct *tty) | 1480 | void stop_tty(struct tty_struct *tty) |
1226 | { | 1481 | { |
1227 | if (tty->stopped) | 1482 | if (tty->stopped) |
@@ -1238,6 +1493,19 @@ void stop_tty(struct tty_struct *tty) | |||
1238 | 1493 | ||
1239 | EXPORT_SYMBOL(stop_tty); | 1494 | EXPORT_SYMBOL(stop_tty); |
1240 | 1495 | ||
1496 | /** | ||
1497 | * start_tty - propogate flow control | ||
1498 | * @tty: tty to start | ||
1499 | * | ||
1500 | * Start a tty that has been stopped if at all possible. Perform | ||
1501 | * any neccessary wakeups and propogate the TIOCPKT status. If this | ||
1502 | * is the tty was previous stopped and is being started then the | ||
1503 | * driver start method is invoked and the line discipline woken. | ||
1504 | * | ||
1505 | * Locking: | ||
1506 | * Broken. Relies on BKL which is unsafe here. | ||
1507 | */ | ||
1508 | |||
1241 | void start_tty(struct tty_struct *tty) | 1509 | void start_tty(struct tty_struct *tty) |
1242 | { | 1510 | { |
1243 | if (!tty->stopped || tty->flow_stopped) | 1511 | if (!tty->stopped || tty->flow_stopped) |
@@ -1258,6 +1526,23 @@ void start_tty(struct tty_struct *tty) | |||
1258 | 1526 | ||
1259 | EXPORT_SYMBOL(start_tty); | 1527 | EXPORT_SYMBOL(start_tty); |
1260 | 1528 | ||
1529 | /** | ||
1530 | * tty_read - read method for tty device files | ||
1531 | * @file: pointer to tty file | ||
1532 | * @buf: user buffer | ||
1533 | * @count: size of user buffer | ||
1534 | * @ppos: unused | ||
1535 | * | ||
1536 | * Perform the read system call function on this terminal device. Checks | ||
1537 | * for hung up devices before calling the line discipline method. | ||
1538 | * | ||
1539 | * Locking: | ||
1540 | * Locks the line discipline internally while needed | ||
1541 | * For historical reasons the line discipline read method is | ||
1542 | * invoked under the BKL. This will go away in time so do not rely on it | ||
1543 | * in new code. Multiple read calls may be outstanding in parallel. | ||
1544 | */ | ||
1545 | |||
1261 | static ssize_t tty_read(struct file * file, char __user * buf, size_t count, | 1546 | static ssize_t tty_read(struct file * file, char __user * buf, size_t count, |
1262 | loff_t *ppos) | 1547 | loff_t *ppos) |
1263 | { | 1548 | { |
@@ -1302,6 +1587,7 @@ static inline ssize_t do_tty_write( | |||
1302 | ssize_t ret = 0, written = 0; | 1587 | ssize_t ret = 0, written = 0; |
1303 | unsigned int chunk; | 1588 | unsigned int chunk; |
1304 | 1589 | ||
1590 | /* FIXME: O_NDELAY ... */ | ||
1305 | if (mutex_lock_interruptible(&tty->atomic_write_lock)) { | 1591 | if (mutex_lock_interruptible(&tty->atomic_write_lock)) { |
1306 | return -ERESTARTSYS; | 1592 | return -ERESTARTSYS; |
1307 | } | 1593 | } |
@@ -1318,6 +1604,9 @@ static inline ssize_t do_tty_write( | |||
1318 | * layer has problems with bigger chunks. It will | 1604 | * layer has problems with bigger chunks. It will |
1319 | * claim to be able to handle more characters than | 1605 | * claim to be able to handle more characters than |
1320 | * it actually does. | 1606 | * it actually does. |
1607 | * | ||
1608 | * FIXME: This can probably go away now except that 64K chunks | ||
1609 | * are too likely to fail unless switched to vmalloc... | ||
1321 | */ | 1610 | */ |
1322 | chunk = 2048; | 1611 | chunk = 2048; |
1323 | if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) | 1612 | if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) |
@@ -1375,6 +1664,24 @@ static inline ssize_t do_tty_write( | |||
1375 | } | 1664 | } |
1376 | 1665 | ||
1377 | 1666 | ||
1667 | /** | ||
1668 | * tty_write - write method for tty device file | ||
1669 | * @file: tty file pointer | ||
1670 | * @buf: user data to write | ||
1671 | * @count: bytes to write | ||
1672 | * @ppos: unused | ||
1673 | * | ||
1674 | * Write data to a tty device via the line discipline. | ||
1675 | * | ||
1676 | * Locking: | ||
1677 | * Locks the line discipline as required | ||
1678 | * Writes to the tty driver are serialized by the atomic_write_lock | ||
1679 | * and are then processed in chunks to the device. The line discipline | ||
1680 | * write method will not be involked in parallel for each device | ||
1681 | * The line discipline write method is called under the big | ||
1682 | * kernel lock for historical reasons. New code should not rely on this. | ||
1683 | */ | ||
1684 | |||
1378 | static ssize_t tty_write(struct file * file, const char __user * buf, size_t count, | 1685 | static ssize_t tty_write(struct file * file, const char __user * buf, size_t count, |
1379 | loff_t *ppos) | 1686 | loff_t *ppos) |
1380 | { | 1687 | { |
@@ -1422,7 +1729,18 @@ ssize_t redirected_tty_write(struct file * file, const char __user * buf, size_t | |||
1422 | 1729 | ||
1423 | static char ptychar[] = "pqrstuvwxyzabcde"; | 1730 | static char ptychar[] = "pqrstuvwxyzabcde"; |
1424 | 1731 | ||
1425 | static inline void pty_line_name(struct tty_driver *driver, int index, char *p) | 1732 | /** |
1733 | * pty_line_name - generate name for a pty | ||
1734 | * @driver: the tty driver in use | ||
1735 | * @index: the minor number | ||
1736 | * @p: output buffer of at least 6 bytes | ||
1737 | * | ||
1738 | * Generate a name from a driver reference and write it to the output | ||
1739 | * buffer. | ||
1740 | * | ||
1741 | * Locking: None | ||
1742 | */ | ||
1743 | static void pty_line_name(struct tty_driver *driver, int index, char *p) | ||
1426 | { | 1744 | { |
1427 | int i = index + driver->name_base; | 1745 | int i = index + driver->name_base; |
1428 | /* ->name is initialized to "ttyp", but "tty" is expected */ | 1746 | /* ->name is initialized to "ttyp", but "tty" is expected */ |
@@ -1431,24 +1749,53 @@ static inline void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1431 | ptychar[i >> 4 & 0xf], i & 0xf); | 1749 | ptychar[i >> 4 & 0xf], i & 0xf); |
1432 | } | 1750 | } |
1433 | 1751 | ||
1434 | static inline void tty_line_name(struct tty_driver *driver, int index, char *p) | 1752 | /** |
1753 | * pty_line_name - generate name for a tty | ||
1754 | * @driver: the tty driver in use | ||
1755 | * @index: the minor number | ||
1756 | * @p: output buffer of at least 7 bytes | ||
1757 | * | ||
1758 | * Generate a name from a driver reference and write it to the output | ||
1759 | * buffer. | ||
1760 | * | ||
1761 | * Locking: None | ||
1762 | */ | ||
1763 | static void tty_line_name(struct tty_driver *driver, int index, char *p) | ||
1435 | { | 1764 | { |
1436 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | 1765 | sprintf(p, "%s%d", driver->name, index + driver->name_base); |
1437 | } | 1766 | } |
1438 | 1767 | ||
1439 | /* | 1768 | /** |
1769 | * init_dev - initialise a tty device | ||
1770 | * @driver: tty driver we are opening a device on | ||
1771 | * @idx: device index | ||
1772 | * @tty: returned tty structure | ||
1773 | * | ||
1774 | * Prepare a tty device. This may not be a "new" clean device but | ||
1775 | * could also be an active device. The pty drivers require special | ||
1776 | * handling because of this. | ||
1777 | * | ||
1778 | * Locking: | ||
1779 | * The function is called under the tty_mutex, which | ||
1780 | * protects us from the tty struct or driver itself going away. | ||
1781 | * | ||
1782 | * On exit the tty device has the line discipline attached and | ||
1783 | * a reference count of 1. If a pair was created for pty/tty use | ||
1784 | * and the other was a pty master then it too has a reference count of 1. | ||
1785 | * | ||
1440 | * WSH 06/09/97: Rewritten to remove races and properly clean up after a | 1786 | * WSH 06/09/97: Rewritten to remove races and properly clean up after a |
1441 | * failed open. The new code protects the open with a mutex, so it's | 1787 | * failed open. The new code protects the open with a mutex, so it's |
1442 | * really quite straightforward. The mutex locking can probably be | 1788 | * really quite straightforward. The mutex locking can probably be |
1443 | * relaxed for the (most common) case of reopening a tty. | 1789 | * relaxed for the (most common) case of reopening a tty. |
1444 | */ | 1790 | */ |
1791 | |||
1445 | static int init_dev(struct tty_driver *driver, int idx, | 1792 | static int init_dev(struct tty_driver *driver, int idx, |
1446 | struct tty_struct **ret_tty) | 1793 | struct tty_struct **ret_tty) |
1447 | { | 1794 | { |
1448 | struct tty_struct *tty, *o_tty; | 1795 | struct tty_struct *tty, *o_tty; |
1449 | struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1796 | struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; |
1450 | struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | 1797 | struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; |
1451 | int retval=0; | 1798 | int retval = 0; |
1452 | 1799 | ||
1453 | /* check whether we're reopening an existing tty */ | 1800 | /* check whether we're reopening an existing tty */ |
1454 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | 1801 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { |
@@ -1662,10 +2009,20 @@ release_mem_out: | |||
1662 | goto end_init; | 2009 | goto end_init; |
1663 | } | 2010 | } |
1664 | 2011 | ||
1665 | /* | 2012 | /** |
1666 | * Releases memory associated with a tty structure, and clears out the | 2013 | * release_mem - release tty structure memory |
1667 | * driver table slots. | 2014 | * |
2015 | * Releases memory associated with a tty structure, and clears out the | ||
2016 | * driver table slots. This function is called when a device is no longer | ||
2017 | * in use. It also gets called when setup of a device fails. | ||
2018 | * | ||
2019 | * Locking: | ||
2020 | * tty_mutex - sometimes only | ||
2021 | * takes the file list lock internally when working on the list | ||
2022 | * of ttys that the driver keeps. | ||
2023 | * FIXME: should we require tty_mutex is held here ?? | ||
1668 | */ | 2024 | */ |
2025 | |||
1669 | static void release_mem(struct tty_struct *tty, int idx) | 2026 | static void release_mem(struct tty_struct *tty, int idx) |
1670 | { | 2027 | { |
1671 | struct tty_struct *o_tty; | 2028 | struct tty_struct *o_tty; |
@@ -2006,18 +2363,27 @@ static void release_dev(struct file * filp) | |||
2006 | 2363 | ||
2007 | } | 2364 | } |
2008 | 2365 | ||
2009 | /* | 2366 | /** |
2010 | * tty_open and tty_release keep up the tty count that contains the | 2367 | * tty_open - open a tty device |
2011 | * number of opens done on a tty. We cannot use the inode-count, as | 2368 | * @inode: inode of device file |
2012 | * different inodes might point to the same tty. | 2369 | * @filp: file pointer to tty |
2013 | * | 2370 | * |
2014 | * Open-counting is needed for pty masters, as well as for keeping | 2371 | * tty_open and tty_release keep up the tty count that contains the |
2015 | * track of serial lines: DTR is dropped when the last close happens. | 2372 | * number of opens done on a tty. We cannot use the inode-count, as |
2016 | * (This is not done solely through tty->count, now. - Ted 1/27/92) | 2373 | * different inodes might point to the same tty. |
2017 | * | 2374 | * |
2018 | * The termios state of a pty is reset on first open so that | 2375 | * Open-counting is needed for pty masters, as well as for keeping |
2019 | * settings don't persist across reuse. | 2376 | * track of serial lines: DTR is dropped when the last close happens. |
2377 | * (This is not done solely through tty->count, now. - Ted 1/27/92) | ||
2378 | * | ||
2379 | * The termios state of a pty is reset on first open so that | ||
2380 | * settings don't persist across reuse. | ||
2381 | * | ||
2382 | * Locking: tty_mutex protects current->signal->tty, get_tty_driver and | ||
2383 | * init_dev work. tty->count should protect the rest. | ||
2384 | * task_lock is held to update task details for sessions | ||
2020 | */ | 2385 | */ |
2386 | |||
2021 | static int tty_open(struct inode * inode, struct file * filp) | 2387 | static int tty_open(struct inode * inode, struct file * filp) |
2022 | { | 2388 | { |
2023 | struct tty_struct *tty; | 2389 | struct tty_struct *tty; |
@@ -2132,6 +2498,18 @@ got_driver: | |||
2132 | } | 2498 | } |
2133 | 2499 | ||
2134 | #ifdef CONFIG_UNIX98_PTYS | 2500 | #ifdef CONFIG_UNIX98_PTYS |
2501 | /** | ||
2502 | * ptmx_open - open a unix 98 pty master | ||
2503 | * @inode: inode of device file | ||
2504 | * @filp: file pointer to tty | ||
2505 | * | ||
2506 | * Allocate a unix98 pty master device from the ptmx driver. | ||
2507 | * | ||
2508 | * Locking: tty_mutex protects theinit_dev work. tty->count should | ||
2509 | protect the rest. | ||
2510 | * allocated_ptys_lock handles the list of free pty numbers | ||
2511 | */ | ||
2512 | |||
2135 | static int ptmx_open(struct inode * inode, struct file * filp) | 2513 | static int ptmx_open(struct inode * inode, struct file * filp) |
2136 | { | 2514 | { |
2137 | struct tty_struct *tty; | 2515 | struct tty_struct *tty; |
@@ -2191,6 +2569,18 @@ out: | |||
2191 | } | 2569 | } |
2192 | #endif | 2570 | #endif |
2193 | 2571 | ||
2572 | /** | ||
2573 | * tty_release - vfs callback for close | ||
2574 | * @inode: inode of tty | ||
2575 | * @filp: file pointer for handle to tty | ||
2576 | * | ||
2577 | * Called the last time each file handle is closed that references | ||
2578 | * this tty. There may however be several such references. | ||
2579 | * | ||
2580 | * Locking: | ||
2581 | * Takes bkl. See release_dev | ||
2582 | */ | ||
2583 | |||
2194 | static int tty_release(struct inode * inode, struct file * filp) | 2584 | static int tty_release(struct inode * inode, struct file * filp) |
2195 | { | 2585 | { |
2196 | lock_kernel(); | 2586 | lock_kernel(); |
@@ -2199,7 +2589,18 @@ static int tty_release(struct inode * inode, struct file * filp) | |||
2199 | return 0; | 2589 | return 0; |
2200 | } | 2590 | } |
2201 | 2591 | ||
2202 | /* No kernel lock held - fine */ | 2592 | /** |
2593 | * tty_poll - check tty status | ||
2594 | * @filp: file being polled | ||
2595 | * @wait: poll wait structures to update | ||
2596 | * | ||
2597 | * Call the line discipline polling method to obtain the poll | ||
2598 | * status of the device. | ||
2599 | * | ||
2600 | * Locking: locks called line discipline but ldisc poll method | ||
2601 | * may be re-entered freely by other callers. | ||
2602 | */ | ||
2603 | |||
2203 | static unsigned int tty_poll(struct file * filp, poll_table * wait) | 2604 | static unsigned int tty_poll(struct file * filp, poll_table * wait) |
2204 | { | 2605 | { |
2205 | struct tty_struct * tty; | 2606 | struct tty_struct * tty; |
@@ -2243,6 +2644,21 @@ static int tty_fasync(int fd, struct file * filp, int on) | |||
2243 | return 0; | 2644 | return 0; |
2244 | } | 2645 | } |
2245 | 2646 | ||
2647 | /** | ||
2648 | * tiocsti - fake input character | ||
2649 | * @tty: tty to fake input into | ||
2650 | * @p: pointer to character | ||
2651 | * | ||
2652 | * Fake input to a tty device. Does the neccessary locking and | ||
2653 | * input management. | ||
2654 | * | ||
2655 | * FIXME: does not honour flow control ?? | ||
2656 | * | ||
2657 | * Locking: | ||
2658 | * Called functions take tty_ldisc_lock | ||
2659 | * current->signal->tty check is safe without locks | ||
2660 | */ | ||
2661 | |||
2246 | static int tiocsti(struct tty_struct *tty, char __user *p) | 2662 | static int tiocsti(struct tty_struct *tty, char __user *p) |
2247 | { | 2663 | { |
2248 | char ch, mbz = 0; | 2664 | char ch, mbz = 0; |
@@ -2258,6 +2674,18 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2258 | return 0; | 2674 | return 0; |
2259 | } | 2675 | } |
2260 | 2676 | ||
2677 | /** | ||
2678 | * tiocgwinsz - implement window query ioctl | ||
2679 | * @tty; tty | ||
2680 | * @arg: user buffer for result | ||
2681 | * | ||
2682 | * Copies the kernel idea of the window size into the user buffer. No | ||
2683 | * locking is done. | ||
2684 | * | ||
2685 | * FIXME: Returning random values racing a window size set is wrong | ||
2686 | * should lock here against that | ||
2687 | */ | ||
2688 | |||
2261 | static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) | 2689 | static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) |
2262 | { | 2690 | { |
2263 | if (copy_to_user(arg, &tty->winsize, sizeof(*arg))) | 2691 | if (copy_to_user(arg, &tty->winsize, sizeof(*arg))) |
@@ -2265,6 +2693,24 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) | |||
2265 | return 0; | 2693 | return 0; |
2266 | } | 2694 | } |
2267 | 2695 | ||
2696 | /** | ||
2697 | * tiocswinsz - implement window size set ioctl | ||
2698 | * @tty; tty | ||
2699 | * @arg: user buffer for result | ||
2700 | * | ||
2701 | * Copies the user idea of the window size to the kernel. Traditionally | ||
2702 | * this is just advisory information but for the Linux console it | ||
2703 | * actually has driver level meaning and triggers a VC resize. | ||
2704 | * | ||
2705 | * Locking: | ||
2706 | * The console_sem is used to ensure we do not try and resize | ||
2707 | * the console twice at once. | ||
2708 | * FIXME: Two racing size sets may leave the console and kernel | ||
2709 | * parameters disagreeing. Is this exploitable ? | ||
2710 | * FIXME: Random values racing a window size get is wrong | ||
2711 | * should lock here against that | ||
2712 | */ | ||
2713 | |||
2268 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | 2714 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, |
2269 | struct winsize __user * arg) | 2715 | struct winsize __user * arg) |
2270 | { | 2716 | { |
@@ -2294,6 +2740,15 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | |||
2294 | return 0; | 2740 | return 0; |
2295 | } | 2741 | } |
2296 | 2742 | ||
2743 | /** | ||
2744 | * tioccons - allow admin to move logical console | ||
2745 | * @file: the file to become console | ||
2746 | * | ||
2747 | * Allow the adminstrator to move the redirected console device | ||
2748 | * | ||
2749 | * Locking: uses redirect_lock to guard the redirect information | ||
2750 | */ | ||
2751 | |||
2297 | static int tioccons(struct file *file) | 2752 | static int tioccons(struct file *file) |
2298 | { | 2753 | { |
2299 | if (!capable(CAP_SYS_ADMIN)) | 2754 | if (!capable(CAP_SYS_ADMIN)) |
@@ -2319,6 +2774,17 @@ static int tioccons(struct file *file) | |||
2319 | return 0; | 2774 | return 0; |
2320 | } | 2775 | } |
2321 | 2776 | ||
2777 | /** | ||
2778 | * fionbio - non blocking ioctl | ||
2779 | * @file: file to set blocking value | ||
2780 | * @p: user parameter | ||
2781 | * | ||
2782 | * Historical tty interfaces had a blocking control ioctl before | ||
2783 | * the generic functionality existed. This piece of history is preserved | ||
2784 | * in the expected tty API of posix OS's. | ||
2785 | * | ||
2786 | * Locking: none, the open fle handle ensures it won't go away. | ||
2787 | */ | ||
2322 | 2788 | ||
2323 | static int fionbio(struct file *file, int __user *p) | 2789 | static int fionbio(struct file *file, int __user *p) |
2324 | { | 2790 | { |
@@ -2334,6 +2800,23 @@ static int fionbio(struct file *file, int __user *p) | |||
2334 | return 0; | 2800 | return 0; |
2335 | } | 2801 | } |
2336 | 2802 | ||
2803 | /** | ||
2804 | * tiocsctty - set controlling tty | ||
2805 | * @tty: tty structure | ||
2806 | * @arg: user argument | ||
2807 | * | ||
2808 | * This ioctl is used to manage job control. It permits a session | ||
2809 | * leader to set this tty as the controlling tty for the session. | ||
2810 | * | ||
2811 | * Locking: | ||
2812 | * Takes tasklist lock internally to walk sessions | ||
2813 | * Takes task_lock() when updating signal->tty | ||
2814 | * | ||
2815 | * FIXME: tty_mutex is needed to protect signal->tty references. | ||
2816 | * FIXME: why task_lock on the signal->tty reference ?? | ||
2817 | * | ||
2818 | */ | ||
2819 | |||
2337 | static int tiocsctty(struct tty_struct *tty, int arg) | 2820 | static int tiocsctty(struct tty_struct *tty, int arg) |
2338 | { | 2821 | { |
2339 | struct task_struct *p; | 2822 | struct task_struct *p; |
@@ -2374,6 +2857,18 @@ static int tiocsctty(struct tty_struct *tty, int arg) | |||
2374 | return 0; | 2857 | return 0; |
2375 | } | 2858 | } |
2376 | 2859 | ||
2860 | /** | ||
2861 | * tiocgpgrp - get process group | ||
2862 | * @tty: tty passed by user | ||
2863 | * @real_tty: tty side of the tty pased by the user if a pty else the tty | ||
2864 | * @p: returned pid | ||
2865 | * | ||
2866 | * Obtain the process group of the tty. If there is no process group | ||
2867 | * return an error. | ||
2868 | * | ||
2869 | * Locking: none. Reference to ->signal->tty is safe. | ||
2870 | */ | ||
2871 | |||
2377 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2872 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2378 | { | 2873 | { |
2379 | /* | 2874 | /* |
@@ -2385,6 +2880,20 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2385 | return put_user(real_tty->pgrp, p); | 2880 | return put_user(real_tty->pgrp, p); |
2386 | } | 2881 | } |
2387 | 2882 | ||
2883 | /** | ||
2884 | * tiocspgrp - attempt to set process group | ||
2885 | * @tty: tty passed by user | ||
2886 | * @real_tty: tty side device matching tty passed by user | ||
2887 | * @p: pid pointer | ||
2888 | * | ||
2889 | * Set the process group of the tty to the session passed. Only | ||
2890 | * permitted where the tty session is our session. | ||
2891 | * | ||
2892 | * Locking: None | ||
2893 | * | ||
2894 | * FIXME: current->signal->tty referencing is unsafe. | ||
2895 | */ | ||
2896 | |||
2388 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2897 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2389 | { | 2898 | { |
2390 | pid_t pgrp; | 2899 | pid_t pgrp; |
@@ -2408,6 +2917,18 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2408 | return 0; | 2917 | return 0; |
2409 | } | 2918 | } |
2410 | 2919 | ||
2920 | /** | ||
2921 | * tiocgsid - get session id | ||
2922 | * @tty: tty passed by user | ||
2923 | * @real_tty: tty side of the tty pased by the user if a pty else the tty | ||
2924 | * @p: pointer to returned session id | ||
2925 | * | ||
2926 | * Obtain the session id of the tty. If there is no session | ||
2927 | * return an error. | ||
2928 | * | ||
2929 | * Locking: none. Reference to ->signal->tty is safe. | ||
2930 | */ | ||
2931 | |||
2411 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2932 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2412 | { | 2933 | { |
2413 | /* | 2934 | /* |
@@ -2421,6 +2942,16 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ | |||
2421 | return put_user(real_tty->session, p); | 2942 | return put_user(real_tty->session, p); |
2422 | } | 2943 | } |
2423 | 2944 | ||
2945 | /** | ||
2946 | * tiocsetd - set line discipline | ||
2947 | * @tty: tty device | ||
2948 | * @p: pointer to user data | ||
2949 | * | ||
2950 | * Set the line discipline according to user request. | ||
2951 | * | ||
2952 | * Locking: see tty_set_ldisc, this function is just a helper | ||
2953 | */ | ||
2954 | |||
2424 | static int tiocsetd(struct tty_struct *tty, int __user *p) | 2955 | static int tiocsetd(struct tty_struct *tty, int __user *p) |
2425 | { | 2956 | { |
2426 | int ldisc; | 2957 | int ldisc; |
@@ -2430,6 +2961,21 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) | |||
2430 | return tty_set_ldisc(tty, ldisc); | 2961 | return tty_set_ldisc(tty, ldisc); |
2431 | } | 2962 | } |
2432 | 2963 | ||
2964 | /** | ||
2965 | * send_break - performed time break | ||
2966 | * @tty: device to break on | ||
2967 | * @duration: timeout in mS | ||
2968 | * | ||
2969 | * Perform a timed break on hardware that lacks its own driver level | ||
2970 | * timed break functionality. | ||
2971 | * | ||
2972 | * Locking: | ||
2973 | * None | ||
2974 | * | ||
2975 | * FIXME: | ||
2976 | * What if two overlap | ||
2977 | */ | ||
2978 | |||
2433 | static int send_break(struct tty_struct *tty, unsigned int duration) | 2979 | static int send_break(struct tty_struct *tty, unsigned int duration) |
2434 | { | 2980 | { |
2435 | tty->driver->break_ctl(tty, -1); | 2981 | tty->driver->break_ctl(tty, -1); |
@@ -2442,8 +2988,19 @@ static int send_break(struct tty_struct *tty, unsigned int duration) | |||
2442 | return 0; | 2988 | return 0; |
2443 | } | 2989 | } |
2444 | 2990 | ||
2445 | static int | 2991 | /** |
2446 | tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) | 2992 | * tiocmget - get modem status |
2993 | * @tty: tty device | ||
2994 | * @file: user file pointer | ||
2995 | * @p: pointer to result | ||
2996 | * | ||
2997 | * Obtain the modem status bits from the tty driver if the feature | ||
2998 | * is supported. Return -EINVAL if it is not available. | ||
2999 | * | ||
3000 | * Locking: none (up to the driver) | ||
3001 | */ | ||
3002 | |||
3003 | static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) | ||
2447 | { | 3004 | { |
2448 | int retval = -EINVAL; | 3005 | int retval = -EINVAL; |
2449 | 3006 | ||
@@ -2456,8 +3013,20 @@ tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) | |||
2456 | return retval; | 3013 | return retval; |
2457 | } | 3014 | } |
2458 | 3015 | ||
2459 | static int | 3016 | /** |
2460 | tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, | 3017 | * tiocmset - set modem status |
3018 | * @tty: tty device | ||
3019 | * @file: user file pointer | ||
3020 | * @cmd: command - clear bits, set bits or set all | ||
3021 | * @p: pointer to desired bits | ||
3022 | * | ||
3023 | * Set the modem status bits from the tty driver if the feature | ||
3024 | * is supported. Return -EINVAL if it is not available. | ||
3025 | * | ||
3026 | * Locking: none (up to the driver) | ||
3027 | */ | ||
3028 | |||
3029 | static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, | ||
2461 | unsigned __user *p) | 3030 | unsigned __user *p) |
2462 | { | 3031 | { |
2463 | int retval = -EINVAL; | 3032 | int retval = -EINVAL; |
@@ -2573,6 +3142,7 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
2573 | clear_bit(TTY_EXCLUSIVE, &tty->flags); | 3142 | clear_bit(TTY_EXCLUSIVE, &tty->flags); |
2574 | return 0; | 3143 | return 0; |
2575 | case TIOCNOTTY: | 3144 | case TIOCNOTTY: |
3145 | /* FIXME: taks lock or tty_mutex ? */ | ||
2576 | if (current->signal->tty != tty) | 3146 | if (current->signal->tty != tty) |
2577 | return -ENOTTY; | 3147 | return -ENOTTY; |
2578 | if (current->signal->leader) | 3148 | if (current->signal->leader) |
@@ -2753,9 +3323,16 @@ void do_SAK(struct tty_struct *tty) | |||
2753 | 3323 | ||
2754 | EXPORT_SYMBOL(do_SAK); | 3324 | EXPORT_SYMBOL(do_SAK); |
2755 | 3325 | ||
2756 | /* | 3326 | /** |
2757 | * This routine is called out of the software interrupt to flush data | 3327 | * flush_to_ldisc |
2758 | * from the buffer chain to the line discipline. | 3328 | * @private_: tty structure passed from work queue. |
3329 | * | ||
3330 | * This routine is called out of the software interrupt to flush data | ||
3331 | * from the buffer chain to the line discipline. | ||
3332 | * | ||
3333 | * Locking: holds tty->buf.lock to guard buffer list. Drops the lock | ||
3334 | * while invoking the line discipline receive_buf method. The | ||
3335 | * receive_buf method is single threaded for each tty instance. | ||
2759 | */ | 3336 | */ |
2760 | 3337 | ||
2761 | static void flush_to_ldisc(void *private_) | 3338 | static void flush_to_ldisc(void *private_) |
@@ -2831,6 +3408,8 @@ static int n_baud_table = ARRAY_SIZE(baud_table); | |||
2831 | * Convert termios baud rate data into a speed. This should be called | 3408 | * Convert termios baud rate data into a speed. This should be called |
2832 | * with the termios lock held if this termios is a terminal termios | 3409 | * with the termios lock held if this termios is a terminal termios |
2833 | * structure. May change the termios data. | 3410 | * structure. May change the termios data. |
3411 | * | ||
3412 | * Locking: none | ||
2834 | */ | 3413 | */ |
2835 | 3414 | ||
2836 | int tty_termios_baud_rate(struct termios *termios) | 3415 | int tty_termios_baud_rate(struct termios *termios) |
@@ -2859,6 +3438,8 @@ EXPORT_SYMBOL(tty_termios_baud_rate); | |||
2859 | * Returns the baud rate as an integer for this terminal. The | 3438 | * Returns the baud rate as an integer for this terminal. The |
2860 | * termios lock must be held by the caller and the terminal bit | 3439 | * termios lock must be held by the caller and the terminal bit |
2861 | * flags may be updated. | 3440 | * flags may be updated. |
3441 | * | ||
3442 | * Locking: none | ||
2862 | */ | 3443 | */ |
2863 | 3444 | ||
2864 | int tty_get_baud_rate(struct tty_struct *tty) | 3445 | int tty_get_baud_rate(struct tty_struct *tty) |
@@ -2888,6 +3469,8 @@ EXPORT_SYMBOL(tty_get_baud_rate); | |||
2888 | * | 3469 | * |
2889 | * In the event of the queue being busy for flipping the work will be | 3470 | * In the event of the queue being busy for flipping the work will be |
2890 | * held off and retried later. | 3471 | * held off and retried later. |
3472 | * | ||
3473 | * Locking: tty buffer lock. Driver locks in low latency mode. | ||
2891 | */ | 3474 | */ |
2892 | 3475 | ||
2893 | void tty_flip_buffer_push(struct tty_struct *tty) | 3476 | void tty_flip_buffer_push(struct tty_struct *tty) |
@@ -2907,9 +3490,16 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
2907 | EXPORT_SYMBOL(tty_flip_buffer_push); | 3490 | EXPORT_SYMBOL(tty_flip_buffer_push); |
2908 | 3491 | ||
2909 | 3492 | ||
2910 | /* | 3493 | /** |
2911 | * This subroutine initializes a tty structure. | 3494 | * initialize_tty_struct |
3495 | * @tty: tty to initialize | ||
3496 | * | ||
3497 | * This subroutine initializes a tty structure that has been newly | ||
3498 | * allocated. | ||
3499 | * | ||
3500 | * Locking: none - tty in question must not be exposed at this point | ||
2912 | */ | 3501 | */ |
3502 | |||
2913 | static void initialize_tty_struct(struct tty_struct *tty) | 3503 | static void initialize_tty_struct(struct tty_struct *tty) |
2914 | { | 3504 | { |
2915 | memset(tty, 0, sizeof(struct tty_struct)); | 3505 | memset(tty, 0, sizeof(struct tty_struct)); |
@@ -2935,6 +3525,7 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
2935 | /* | 3525 | /* |
2936 | * The default put_char routine if the driver did not define one. | 3526 | * The default put_char routine if the driver did not define one. |
2937 | */ | 3527 | */ |
3528 | |||
2938 | static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) | 3529 | static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) |
2939 | { | 3530 | { |
2940 | tty->driver->write(tty, &ch, 1); | 3531 | tty->driver->write(tty, &ch, 1); |
@@ -2943,19 +3534,23 @@ static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) | |||
2943 | static struct class *tty_class; | 3534 | static struct class *tty_class; |
2944 | 3535 | ||
2945 | /** | 3536 | /** |
2946 | * tty_register_device - register a tty device | 3537 | * tty_register_device - register a tty device |
2947 | * @driver: the tty driver that describes the tty device | 3538 | * @driver: the tty driver that describes the tty device |
2948 | * @index: the index in the tty driver for this tty device | 3539 | * @index: the index in the tty driver for this tty device |
2949 | * @device: a struct device that is associated with this tty device. | 3540 | * @device: a struct device that is associated with this tty device. |
2950 | * This field is optional, if there is no known struct device for this | 3541 | * This field is optional, if there is no known struct device |
2951 | * tty device it can be set to NULL safely. | 3542 | * for this tty device it can be set to NULL safely. |
2952 | * | 3543 | * |
2953 | * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). | 3544 | * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). |
2954 | * | 3545 | * |
2955 | * This call is required to be made to register an individual tty device if | 3546 | * This call is required to be made to register an individual tty device |
2956 | * the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If that | 3547 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If |
2957 | * bit is not set, this function should not be called by a tty driver. | 3548 | * that bit is not set, this function should not be called by a tty |
3549 | * driver. | ||
3550 | * | ||
3551 | * Locking: ?? | ||
2958 | */ | 3552 | */ |
3553 | |||
2959 | struct class_device *tty_register_device(struct tty_driver *driver, | 3554 | struct class_device *tty_register_device(struct tty_driver *driver, |
2960 | unsigned index, struct device *device) | 3555 | unsigned index, struct device *device) |
2961 | { | 3556 | { |
@@ -2977,13 +3572,16 @@ struct class_device *tty_register_device(struct tty_driver *driver, | |||
2977 | } | 3572 | } |
2978 | 3573 | ||
2979 | /** | 3574 | /** |
2980 | * tty_unregister_device - unregister a tty device | 3575 | * tty_unregister_device - unregister a tty device |
2981 | * @driver: the tty driver that describes the tty device | 3576 | * @driver: the tty driver that describes the tty device |
2982 | * @index: the index in the tty driver for this tty device | 3577 | * @index: the index in the tty driver for this tty device |
2983 | * | 3578 | * |
2984 | * If a tty device is registered with a call to tty_register_device() then | 3579 | * If a tty device is registered with a call to tty_register_device() then |
2985 | * this function must be made when the tty device is gone. | 3580 | * this function must be called when the tty device is gone. |
3581 | * | ||
3582 | * Locking: ?? | ||
2986 | */ | 3583 | */ |
3584 | |||
2987 | void tty_unregister_device(struct tty_driver *driver, unsigned index) | 3585 | void tty_unregister_device(struct tty_driver *driver, unsigned index) |
2988 | { | 3586 | { |
2989 | class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); | 3587 | class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index f19cf9d7792d..4ad47d321bd4 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -36,6 +36,18 @@ | |||
36 | #define TERMIOS_WAIT 2 | 36 | #define TERMIOS_WAIT 2 |
37 | #define TERMIOS_TERMIO 4 | 37 | #define TERMIOS_TERMIO 4 |
38 | 38 | ||
39 | |||
40 | /** | ||
41 | * tty_wait_until_sent - wait for I/O to finish | ||
42 | * @tty: tty we are waiting for | ||
43 | * @timeout: how long we will wait | ||
44 | * | ||
45 | * Wait for characters pending in a tty driver to hit the wire, or | ||
46 | * for a timeout to occur (eg due to flow control) | ||
47 | * | ||
48 | * Locking: none | ||
49 | */ | ||
50 | |||
39 | void tty_wait_until_sent(struct tty_struct * tty, long timeout) | 51 | void tty_wait_until_sent(struct tty_struct * tty, long timeout) |
40 | { | 52 | { |
41 | DECLARE_WAITQUEUE(wait, current); | 53 | DECLARE_WAITQUEUE(wait, current); |
@@ -94,6 +106,18 @@ static void unset_locked_termios(struct termios *termios, | |||
94 | old->c_cc[i] : termios->c_cc[i]; | 106 | old->c_cc[i] : termios->c_cc[i]; |
95 | } | 107 | } |
96 | 108 | ||
109 | /** | ||
110 | * change_termios - update termios values | ||
111 | * @tty: tty to update | ||
112 | * @new_termios: desired new value | ||
113 | * | ||
114 | * Perform updates to the termios values set on this terminal. There | ||
115 | * is a bit of layering violation here with n_tty in terms of the | ||
116 | * internal knowledge of this function. | ||
117 | * | ||
118 | * Locking: termios_sem | ||
119 | */ | ||
120 | |||
97 | static void change_termios(struct tty_struct * tty, struct termios * new_termios) | 121 | static void change_termios(struct tty_struct * tty, struct termios * new_termios) |
98 | { | 122 | { |
99 | int canon_change; | 123 | int canon_change; |
@@ -155,6 +179,19 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios | |||
155 | up(&tty->termios_sem); | 179 | up(&tty->termios_sem); |
156 | } | 180 | } |
157 | 181 | ||
182 | /** | ||
183 | * set_termios - set termios values for a tty | ||
184 | * @tty: terminal device | ||
185 | * @arg: user data | ||
186 | * @opt: option information | ||
187 | * | ||
188 | * Helper function to prepare termios data and run neccessary other | ||
189 | * functions before using change_termios to do the actual changes. | ||
190 | * | ||
191 | * Locking: | ||
192 | * Called functions take ldisc and termios_sem locks | ||
193 | */ | ||
194 | |||
158 | static int set_termios(struct tty_struct * tty, void __user *arg, int opt) | 195 | static int set_termios(struct tty_struct * tty, void __user *arg, int opt) |
159 | { | 196 | { |
160 | struct termios tmp_termios; | 197 | struct termios tmp_termios; |
@@ -284,6 +321,17 @@ static void set_sgflags(struct termios * termios, int flags) | |||
284 | } | 321 | } |
285 | } | 322 | } |
286 | 323 | ||
324 | /** | ||
325 | * set_sgttyb - set legacy terminal values | ||
326 | * @tty: tty structure | ||
327 | * @sgttyb: pointer to old style terminal structure | ||
328 | * | ||
329 | * Updates a terminal from the legacy BSD style terminal information | ||
330 | * structure. | ||
331 | * | ||
332 | * Locking: termios_sem | ||
333 | */ | ||
334 | |||
287 | static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) | 335 | static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) |
288 | { | 336 | { |
289 | int retval; | 337 | int retval; |
@@ -369,9 +417,16 @@ static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars) | |||
369 | } | 417 | } |
370 | #endif | 418 | #endif |
371 | 419 | ||
372 | /* | 420 | /** |
373 | * Send a high priority character to the tty. | 421 | * send_prio_char - send priority character |
422 | * | ||
423 | * Send a high priority character to the tty even if stopped | ||
424 | * | ||
425 | * Locking: none | ||
426 | * | ||
427 | * FIXME: overlapping calls with start/stop tty lose state of tty | ||
374 | */ | 428 | */ |
429 | |||
375 | static void send_prio_char(struct tty_struct *tty, char ch) | 430 | static void send_prio_char(struct tty_struct *tty, char ch) |
376 | { | 431 | { |
377 | int was_stopped = tty->stopped; | 432 | int was_stopped = tty->stopped; |