aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_ioctl.c')
-rw-r--r--drivers/char/tty_ioctl.c362
1 files changed, 180 insertions, 182 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index d4b6d64e858b..f95a80b2265f 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -50,11 +50,11 @@
50 * Locking: none 50 * Locking: none
51 */ 51 */
52 52
53void tty_wait_until_sent(struct tty_struct * tty, long timeout) 53void tty_wait_until_sent(struct tty_struct *tty, long timeout)
54{ 54{
55#ifdef TTY_DEBUG_WAIT_UNTIL_SENT 55#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
56 char buf[64]; 56 char buf[64];
57 57
58 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf)); 58 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
59#endif 59#endif
60 if (!tty->driver->chars_in_buffer) 60 if (!tty->driver->chars_in_buffer)
@@ -67,7 +67,6 @@ void tty_wait_until_sent(struct tty_struct * tty, long timeout)
67 if (tty->driver->wait_until_sent) 67 if (tty->driver->wait_until_sent)
68 tty->driver->wait_until_sent(tty, timeout); 68 tty->driver->wait_until_sent(tty, timeout);
69} 69}
70
71EXPORT_SYMBOL(tty_wait_until_sent); 70EXPORT_SYMBOL(tty_wait_until_sent);
72 71
73static void unset_locked_termios(struct ktermios *termios, 72static void unset_locked_termios(struct ktermios *termios,
@@ -75,8 +74,8 @@ static void unset_locked_termios(struct ktermios *termios,
75 struct ktermios *locked) 74 struct ktermios *locked)
76{ 75{
77 int i; 76 int i;
78 77
79#define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z))) 78#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
80 79
81 if (!locked) { 80 if (!locked) {
82 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n"); 81 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
@@ -88,7 +87,7 @@ static void unset_locked_termios(struct ktermios *termios,
88 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag); 87 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
89 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag); 88 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
90 termios->c_line = locked->c_line ? old->c_line : termios->c_line; 89 termios->c_line = locked->c_line ? old->c_line : termios->c_line;
91 for (i=0; i < NCCS; i++) 90 for (i = 0; i < NCCS; i++)
92 termios->c_cc[i] = locked->c_cc[i] ? 91 termios->c_cc[i] = locked->c_cc[i] ?
93 old->c_cc[i] : termios->c_cc[i]; 92 old->c_cc[i] : termios->c_cc[i];
94 /* FIXME: What should we do for i/ospeed */ 93 /* FIXME: What should we do for i/ospeed */
@@ -163,7 +162,6 @@ speed_t tty_termios_baud_rate(struct ktermios *termios)
163 } 162 }
164 return baud_table[cbaud]; 163 return baud_table[cbaud];
165} 164}
166
167EXPORT_SYMBOL(tty_termios_baud_rate); 165EXPORT_SYMBOL(tty_termios_baud_rate);
168 166
169/** 167/**
@@ -203,7 +201,6 @@ speed_t tty_termios_input_baud_rate(struct ktermios *termios)
203 return tty_termios_baud_rate(termios); 201 return tty_termios_baud_rate(termios);
204#endif 202#endif
205} 203}
206
207EXPORT_SYMBOL(tty_termios_input_baud_rate); 204EXPORT_SYMBOL(tty_termios_input_baud_rate);
208 205
209/** 206/**
@@ -338,7 +335,6 @@ speed_t tty_get_baud_rate(struct tty_struct *tty)
338 335
339 return baud; 336 return baud;
340} 337}
341
342EXPORT_SYMBOL(tty_get_baud_rate); 338EXPORT_SYMBOL(tty_get_baud_rate);
343 339
344/** 340/**
@@ -361,7 +357,6 @@ void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
361 new->c_ispeed = old->c_ispeed; 357 new->c_ispeed = old->c_ispeed;
362 new->c_ospeed = old->c_ospeed; 358 new->c_ospeed = old->c_ospeed;
363} 359}
364
365EXPORT_SYMBOL(tty_termios_copy_hw); 360EXPORT_SYMBOL(tty_termios_copy_hw);
366 361
367/** 362/**
@@ -395,16 +390,16 @@ EXPORT_SYMBOL(tty_termios_hw_change);
395 * Locking: termios_sem 390 * Locking: termios_sem
396 */ 391 */
397 392
398static void change_termios(struct tty_struct * tty, struct ktermios * new_termios) 393static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
399{ 394{
400 int canon_change; 395 int canon_change;
401 struct ktermios old_termios = *tty->termios; 396 struct ktermios old_termios = *tty->termios;
402 struct tty_ldisc *ld; 397 struct tty_ldisc *ld;
403 398
404 /* 399 /*
405 * Perform the actual termios internal changes under lock. 400 * Perform the actual termios internal changes under lock.
406 */ 401 */
407 402
408 403
409 /* FIXME: we need to decide on some locking/ordering semantics 404 /* FIXME: we need to decide on some locking/ordering semantics
410 for the set_termios notification eventually */ 405 for the set_termios notification eventually */
@@ -419,7 +414,7 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio
419 tty->canon_data = 0; 414 tty->canon_data = 0;
420 tty->erasing = 0; 415 tty->erasing = 0;
421 } 416 }
422 417
423 /* This bit should be in the ldisc code */ 418 /* This bit should be in the ldisc code */
424 if (canon_change && !L_ICANON(tty) && tty->read_cnt) 419 if (canon_change && !L_ICANON(tty) && tty->read_cnt)
425 /* Get characters left over from canonical mode. */ 420 /* Get characters left over from canonical mode. */
@@ -442,7 +437,7 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio
442 wake_up_interruptible(&tty->link->read_wait); 437 wake_up_interruptible(&tty->link->read_wait);
443 } 438 }
444 } 439 }
445 440
446 if (tty->driver->set_termios) 441 if (tty->driver->set_termios)
447 (*tty->driver->set_termios)(tty, &old_termios); 442 (*tty->driver->set_termios)(tty, &old_termios);
448 else 443 else
@@ -470,7 +465,7 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio
470 * Called functions take ldisc and termios_sem locks 465 * Called functions take ldisc and termios_sem locks
471 */ 466 */
472 467
473static int set_termios(struct tty_struct * tty, void __user *arg, int opt) 468static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
474{ 469{
475 struct ktermios tmp_termios; 470 struct ktermios tmp_termios;
476 struct tty_ldisc *ld; 471 struct tty_ldisc *ld;
@@ -501,19 +496,19 @@ static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
501 return -EFAULT; 496 return -EFAULT;
502#endif 497#endif
503 498
504 /* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed 499 /* If old style Bfoo values are used then load c_ispeed/c_ospeed
505 so its unconditionally usable */ 500 * with the real speed so its unconditionally usable */
506 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); 501 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
507 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); 502 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
508 503
509 ld = tty_ldisc_ref(tty); 504 ld = tty_ldisc_ref(tty);
510 505
511 if (ld != NULL) { 506 if (ld != NULL) {
512 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer) 507 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
513 ld->flush_buffer(tty); 508 ld->flush_buffer(tty);
514 tty_ldisc_deref(ld); 509 tty_ldisc_deref(ld);
515 } 510 }
516 511
517 if (opt & TERMIOS_WAIT) { 512 if (opt & TERMIOS_WAIT) {
518 tty_wait_until_sent(tty, 0); 513 tty_wait_until_sent(tty, 0);
519 if (signal_pending(current)) 514 if (signal_pending(current))
@@ -529,14 +524,14 @@ static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
529 return 0; 524 return 0;
530} 525}
531 526
532static int get_termio(struct tty_struct * tty, struct termio __user * termio) 527static int get_termio(struct tty_struct *tty, struct termio __user *termio)
533{ 528{
534 if (kernel_termios_to_user_termio(termio, tty->termios)) 529 if (kernel_termios_to_user_termio(termio, tty->termios))
535 return -EFAULT; 530 return -EFAULT;
536 return 0; 531 return 0;
537} 532}
538 533
539static unsigned long inq_canon(struct tty_struct * tty) 534static unsigned long inq_canon(struct tty_struct *tty)
540{ 535{
541 int nr, head, tail; 536 int nr, head, tail;
542 537
@@ -561,7 +556,7 @@ static unsigned long inq_canon(struct tty_struct * tty)
561 * 556 *
562 * The "sg_flags" translation is a joke.. 557 * The "sg_flags" translation is a joke..
563 */ 558 */
564static int get_sgflags(struct tty_struct * tty) 559static int get_sgflags(struct tty_struct *tty)
565{ 560{
566 int flags = 0; 561 int flags = 0;
567 562
@@ -579,7 +574,7 @@ static int get_sgflags(struct tty_struct * tty)
579 return flags; 574 return flags;
580} 575}
581 576
582static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) 577static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
583{ 578{
584 struct sgttyb tmp; 579 struct sgttyb tmp;
585 580
@@ -590,11 +585,11 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
590 tmp.sg_kill = tty->termios->c_cc[VKILL]; 585 tmp.sg_kill = tty->termios->c_cc[VKILL];
591 tmp.sg_flags = get_sgflags(tty); 586 tmp.sg_flags = get_sgflags(tty);
592 mutex_unlock(&tty->termios_mutex); 587 mutex_unlock(&tty->termios_mutex);
593 588
594 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; 589 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
595} 590}
596 591
597static void set_sgflags(struct ktermios * termios, int flags) 592static void set_sgflags(struct ktermios *termios, int flags)
598{ 593{
599 termios->c_iflag = ICRNL | IXON; 594 termios->c_iflag = ICRNL | IXON;
600 termios->c_oflag = 0; 595 termios->c_oflag = 0;
@@ -631,7 +626,7 @@ static void set_sgflags(struct ktermios * termios, int flags)
631 * Locking: termios_sem 626 * Locking: termios_sem
632 */ 627 */
633 628
634static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) 629static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
635{ 630{
636 int retval; 631 int retval;
637 struct sgttyb tmp; 632 struct sgttyb tmp;
@@ -640,7 +635,7 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
640 retval = tty_check_change(tty); 635 retval = tty_check_change(tty);
641 if (retval) 636 if (retval)
642 return retval; 637 return retval;
643 638
644 if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) 639 if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
645 return -EFAULT; 640 return -EFAULT;
646 641
@@ -651,7 +646,8 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
651 set_sgflags(&termios, tmp.sg_flags); 646 set_sgflags(&termios, tmp.sg_flags);
652 /* Try and encode into Bfoo format */ 647 /* Try and encode into Bfoo format */
653#ifdef BOTHER 648#ifdef BOTHER
654 tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed); 649 tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
650 termios.c_ospeed);
655#endif 651#endif
656 mutex_unlock(&tty->termios_mutex); 652 mutex_unlock(&tty->termios_mutex);
657 change_termios(tty, &termios); 653 change_termios(tty, &termios);
@@ -660,7 +656,7 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
660#endif 656#endif
661 657
662#ifdef TIOCGETC 658#ifdef TIOCGETC
663static int get_tchars(struct tty_struct * tty, struct tchars __user * tchars) 659static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
664{ 660{
665 struct tchars tmp; 661 struct tchars tmp;
666 662
@@ -673,7 +669,7 @@ static int get_tchars(struct tty_struct * tty, struct tchars __user * tchars)
673 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 669 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
674} 670}
675 671
676static int set_tchars(struct tty_struct * tty, struct tchars __user * tchars) 672static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
677{ 673{
678 struct tchars tmp; 674 struct tchars tmp;
679 675
@@ -690,20 +686,22 @@ static int set_tchars(struct tty_struct * tty, struct tchars __user * tchars)
690#endif 686#endif
691 687
692#ifdef TIOCGLTC 688#ifdef TIOCGLTC
693static int get_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars) 689static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
694{ 690{
695 struct ltchars tmp; 691 struct ltchars tmp;
696 692
697 tmp.t_suspc = tty->termios->c_cc[VSUSP]; 693 tmp.t_suspc = tty->termios->c_cc[VSUSP];
698 tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; /* what is dsuspc anyway? */ 694 /* what is dsuspc anyway? */
695 tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
699 tmp.t_rprntc = tty->termios->c_cc[VREPRINT]; 696 tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
700 tmp.t_flushc = tty->termios->c_cc[VEOL2]; /* what is flushc anyway? */ 697 /* what is flushc anyway? */
698 tmp.t_flushc = tty->termios->c_cc[VEOL2];
701 tmp.t_werasc = tty->termios->c_cc[VWERASE]; 699 tmp.t_werasc = tty->termios->c_cc[VWERASE];
702 tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; 700 tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
703 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 701 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
704} 702}
705 703
706static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars) 704static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
707{ 705{
708 struct ltchars tmp; 706 struct ltchars tmp;
709 707
@@ -711,9 +709,11 @@ static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
711 return -EFAULT; 709 return -EFAULT;
712 710
713 tty->termios->c_cc[VSUSP] = tmp.t_suspc; 711 tty->termios->c_cc[VSUSP] = tmp.t_suspc;
714 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; /* what is dsuspc anyway? */ 712 /* what is dsuspc anyway? */
713 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
715 tty->termios->c_cc[VREPRINT] = tmp.t_rprntc; 714 tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
716 tty->termios->c_cc[VEOL2] = tmp.t_flushc; /* what is flushc anyway? */ 715 /* what is flushc anyway? */
716 tty->termios->c_cc[VEOL2] = tmp.t_flushc;
717 tty->termios->c_cc[VWERASE] = tmp.t_werasc; 717 tty->termios->c_cc[VWERASE] = tmp.t_werasc;
718 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; 718 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
719 return 0; 719 return 0;
@@ -761,10 +761,10 @@ static int send_prio_char(struct tty_struct *tty, char ch)
761 * consistent mode setting. 761 * consistent mode setting.
762 */ 762 */
763 763
764int tty_mode_ioctl(struct tty_struct * tty, struct file *file, 764int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
765 unsigned int cmd, unsigned long arg) 765 unsigned int cmd, unsigned long arg)
766{ 766{
767 struct tty_struct * real_tty; 767 struct tty_struct *real_tty;
768 void __user *p = (void __user *)arg; 768 void __user *p = (void __user *)arg;
769 769
770 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 770 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -775,100 +775,100 @@ int tty_mode_ioctl(struct tty_struct * tty, struct file *file,
775 775
776 switch (cmd) { 776 switch (cmd) {
777#ifdef TIOCGETP 777#ifdef TIOCGETP
778 case TIOCGETP: 778 case TIOCGETP:
779 return get_sgttyb(real_tty, (struct sgttyb __user *) arg); 779 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
780 case TIOCSETP: 780 case TIOCSETP:
781 case TIOCSETN: 781 case TIOCSETN:
782 return set_sgttyb(real_tty, (struct sgttyb __user *) arg); 782 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
783#endif 783#endif
784#ifdef TIOCGETC 784#ifdef TIOCGETC
785 case TIOCGETC: 785 case TIOCGETC:
786 return get_tchars(real_tty, p); 786 return get_tchars(real_tty, p);
787 case TIOCSETC: 787 case TIOCSETC:
788 return set_tchars(real_tty, p); 788 return set_tchars(real_tty, p);
789#endif 789#endif
790#ifdef TIOCGLTC 790#ifdef TIOCGLTC
791 case TIOCGLTC: 791 case TIOCGLTC:
792 return get_ltchars(real_tty, p); 792 return get_ltchars(real_tty, p);
793 case TIOCSLTC: 793 case TIOCSLTC:
794 return set_ltchars(real_tty, p); 794 return set_ltchars(real_tty, p);
795#endif 795#endif
796 case TCSETSF: 796 case TCSETSF:
797 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD); 797 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
798 case TCSETSW: 798 case TCSETSW:
799 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD); 799 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
800 case TCSETS: 800 case TCSETS:
801 return set_termios(real_tty, p, TERMIOS_OLD); 801 return set_termios(real_tty, p, TERMIOS_OLD);
802#ifndef TCGETS2 802#ifndef TCGETS2
803 case TCGETS: 803 case TCGETS:
804 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) 804 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
805 return -EFAULT; 805 return -EFAULT;
806 return 0; 806 return 0;
807#else 807#else
808 case TCGETS: 808 case TCGETS:
809 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) 809 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
810 return -EFAULT; 810 return -EFAULT;
811 return 0; 811 return 0;
812 case TCGETS2: 812 case TCGETS2:
813 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) 813 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
814 return -EFAULT; 814 return -EFAULT;
815 return 0; 815 return 0;
816 case TCSETSF2: 816 case TCSETSF2:
817 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); 817 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
818 case TCSETSW2: 818 case TCSETSW2:
819 return set_termios(real_tty, p, TERMIOS_WAIT); 819 return set_termios(real_tty, p, TERMIOS_WAIT);
820 case TCSETS2: 820 case TCSETS2:
821 return set_termios(real_tty, p, 0); 821 return set_termios(real_tty, p, 0);
822#endif 822#endif
823 case TCGETA: 823 case TCGETA:
824 return get_termio(real_tty, p); 824 return get_termio(real_tty, p);
825 case TCSETAF: 825 case TCSETAF:
826 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO); 826 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
827 case TCSETAW: 827 case TCSETAW:
828 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO); 828 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
829 case TCSETA: 829 case TCSETA:
830 return set_termios(real_tty, p, TERMIOS_TERMIO); 830 return set_termios(real_tty, p, TERMIOS_TERMIO);
831#ifndef TCGETS2 831#ifndef TCGETS2
832 case TIOCGLCKTRMIOS: 832 case TIOCGLCKTRMIOS:
833 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) 833 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
834 return -EFAULT; 834 return -EFAULT;
835 return 0; 835 return 0;
836 836 case TIOCSLCKTRMIOS:
837 case TIOCSLCKTRMIOS: 837 if (!capable(CAP_SYS_ADMIN))
838 if (!capable(CAP_SYS_ADMIN)) 838 return -EPERM;
839 return -EPERM; 839 if (user_termios_to_kernel_termios(real_tty->termios_locked,
840 if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg)) 840 (struct termios __user *) arg))
841 return -EFAULT; 841 return -EFAULT;
842 return 0; 842 return 0;
843#else 843#else
844 case TIOCGLCKTRMIOS: 844 case TIOCGLCKTRMIOS:
845 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) 845 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
846 return -EFAULT; 846 return -EFAULT;
847 return 0; 847 return 0;
848 848 case TIOCSLCKTRMIOS:
849 case TIOCSLCKTRMIOS: 849 if (!capable(CAP_SYS_ADMIN))
850 if (!capable(CAP_SYS_ADMIN)) 850 return -EPERM;
851 return -EPERM; 851 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
852 if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg)) 852 (struct termios __user *) arg))
853 return -EFAULT; 853 return -EFAULT;
854 return 0; 854 return 0;
855#endif 855#endif
856 case TIOCGSOFTCAR: 856 case TIOCGSOFTCAR:
857 return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg); 857 return put_user(C_CLOCAL(tty) ? 1 : 0,
858 case TIOCSSOFTCAR: 858 (int __user *)arg);
859 if (get_user(arg, (unsigned int __user *) arg)) 859 case TIOCSSOFTCAR:
860 return -EFAULT; 860 if (get_user(arg, (unsigned int __user *) arg))
861 mutex_lock(&tty->termios_mutex); 861 return -EFAULT;
862 tty->termios->c_cflag = 862 mutex_lock(&tty->termios_mutex);
863 ((tty->termios->c_cflag & ~CLOCAL) | 863 tty->termios->c_cflag =
864 (arg ? CLOCAL : 0)); 864 ((tty->termios->c_cflag & ~CLOCAL) |
865 mutex_unlock(&tty->termios_mutex); 865 (arg ? CLOCAL : 0));
866 return 0; 866 mutex_unlock(&tty->termios_mutex);
867 default: 867 return 0;
868 return -ENOIOCTLCMD; 868 default:
869 return -ENOIOCTLCMD;
869 } 870 }
870} 871}
871
872EXPORT_SYMBOL_GPL(tty_mode_ioctl); 872EXPORT_SYMBOL_GPL(tty_mode_ioctl);
873 873
874int tty_perform_flush(struct tty_struct *tty, unsigned long arg) 874int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
@@ -899,13 +899,12 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
899 tty_ldisc_deref(ld); 899 tty_ldisc_deref(ld);
900 return 0; 900 return 0;
901} 901}
902
903EXPORT_SYMBOL_GPL(tty_perform_flush); 902EXPORT_SYMBOL_GPL(tty_perform_flush);
904 903
905int n_tty_ioctl(struct tty_struct * tty, struct file * file, 904int n_tty_ioctl(struct tty_struct *tty, struct file *file,
906 unsigned int cmd, unsigned long arg) 905 unsigned int cmd, unsigned long arg)
907{ 906{
908 struct tty_struct * real_tty; 907 struct tty_struct *real_tty;
909 int retval; 908 int retval;
910 909
911 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 910 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -915,68 +914,67 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
915 real_tty = tty; 914 real_tty = tty;
916 915
917 switch (cmd) { 916 switch (cmd) {
918 case TCXONC: 917 case TCXONC:
919 retval = tty_check_change(tty); 918 retval = tty_check_change(tty);
920 if (retval) 919 if (retval)
921 return retval; 920 return retval;
922 switch (arg) { 921 switch (arg) {
923 case TCOOFF: 922 case TCOOFF:
924 if (!tty->flow_stopped) { 923 if (!tty->flow_stopped) {
925 tty->flow_stopped = 1; 924 tty->flow_stopped = 1;
926 stop_tty(tty); 925 stop_tty(tty);
927 }
928 break;
929 case TCOON:
930 if (tty->flow_stopped) {
931 tty->flow_stopped = 0;
932 start_tty(tty);
933 }
934 break;
935 case TCIOFF:
936 if (STOP_CHAR(tty) != __DISABLED_CHAR)
937 return send_prio_char(tty, STOP_CHAR(tty));
938 break;
939 case TCION:
940 if (START_CHAR(tty) != __DISABLED_CHAR)
941 return send_prio_char(tty, START_CHAR(tty));
942 break;
943 default:
944 return -EINVAL;
945 } 926 }
946 return 0; 927 break;
947 case TCFLSH: 928 case TCOON:
948 return tty_perform_flush(tty, arg); 929 if (tty->flow_stopped) {
949 case TIOCOUTQ: 930 tty->flow_stopped = 0;
950 return put_user(tty->driver->chars_in_buffer ? 931 start_tty(tty);
951 tty->driver->chars_in_buffer(tty) : 0, 932 }
952 (int __user *) arg); 933 break;
953 case TIOCINQ: 934 case TCIOFF:
954 retval = tty->read_cnt; 935 if (STOP_CHAR(tty) != __DISABLED_CHAR)
955 if (L_ICANON(tty)) 936 return send_prio_char(tty, STOP_CHAR(tty));
956 retval = inq_canon(tty); 937 break;
957 return put_user(retval, (unsigned int __user *) arg); 938 case TCION:
958 case TIOCPKT: 939 if (START_CHAR(tty) != __DISABLED_CHAR)
959 { 940 return send_prio_char(tty, START_CHAR(tty));
960 int pktmode; 941 break;
961
962 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
963 tty->driver->subtype != PTY_TYPE_MASTER)
964 return -ENOTTY;
965 if (get_user(pktmode, (int __user *) arg))
966 return -EFAULT;
967 if (pktmode) {
968 if (!tty->packet) {
969 tty->packet = 1;
970 tty->link->ctrl_status = 0;
971 }
972 } else
973 tty->packet = 0;
974 return 0;
975 }
976 default: 942 default:
977 /* Try the mode commands */ 943 return -EINVAL;
978 return tty_mode_ioctl(tty, file, cmd, arg);
979 } 944 }
945 return 0;
946 case TCFLSH:
947 return tty_perform_flush(tty, arg);
948 case TIOCOUTQ:
949 return put_user(tty->driver->chars_in_buffer ?
950 tty->driver->chars_in_buffer(tty) : 0,
951 (int __user *) arg);
952 case TIOCINQ:
953 retval = tty->read_cnt;
954 if (L_ICANON(tty))
955 retval = inq_canon(tty);
956 return put_user(retval, (unsigned int __user *) arg);
957 case TIOCPKT:
958 {
959 int pktmode;
960
961 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
962 tty->driver->subtype != PTY_TYPE_MASTER)
963 return -ENOTTY;
964 if (get_user(pktmode, (int __user *) arg))
965 return -EFAULT;
966 if (pktmode) {
967 if (!tty->packet) {
968 tty->packet = 1;
969 tty->link->ctrl_status = 0;
970 }
971 } else
972 tty->packet = 0;
973 return 0;
974 }
975 default:
976 /* Try the mode commands */
977 return tty_mode_ioctl(tty, file, cmd, arg);
978 }
980} 979}
981
982EXPORT_SYMBOL(n_tty_ioctl); 980EXPORT_SYMBOL(n_tty_ioctl);