This source file includes following definitions.
- _tty_name
- tty_name
- tty_paranoia_check
- tty_register_ldisc
- tty_set_ldisc
- get_tty_driver
- tty_check_change
- hung_up_tty_read
- hung_up_tty_write
- hung_up_tty_select
- hung_up_tty_ioctl
- tty_lseek
- do_tty_hangup
- tty_hangup
- tty_vhangup
- tty_hung_up_p
- disassociate_ctty
- vt_waitactive
- complete_change_console
- change_console
- wait_for_keypress
- stop_tty
- start_tty
- tty_read
- tty_write
- init_dev
- release_dev
- tty_open
- tty_release
- tty_select
- tty_fasync
- do_get_ps_info
- tty_ioctl
- do_SAK
- flush_to_ldisc
- initialize_tty_struct
- tty_default_put_char
- tty_register_driver
- tty_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <linux/types.h>
41 #include <linux/major.h>
42 #include <linux/errno.h>
43 #include <linux/signal.h>
44 #include <linux/fcntl.h>
45 #include <linux/sched.h>
46 #include <linux/interrupt.h>
47 #include <linux/tty.h>
48 #include <linux/tty_flip.h>
49 #include <linux/timer.h>
50 #include <linux/ctype.h>
51 #include <linux/kd.h>
52 #include <linux/mm.h>
53 #include <linux/string.h>
54 #include <linux/malloc.h>
55
56 #include <asm/segment.h>
57 #include <asm/system.h>
58 #include <asm/bitops.h>
59
60 #include "kbd_kern.h"
61 #include "vt_kern.h"
62
63 #define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
64 #define TTY_DEV MKDEV(TTYAUX_MAJOR,0)
65
66 #undef TTY_DEBUG_HANGUP
67
68 #ifdef CONFIG_SELECTION
69 extern int set_selection(const int arg);
70 extern int paste_selection(struct tty_struct *tty);
71 #endif
72 extern int do_screendump(int arg);
73
74 struct termios tty_std_termios;
75 struct tty_driver *tty_drivers;
76 struct tty_ldisc ldiscs[NR_LDISCS];
77
78
79
80
81
82
83 int fg_console = 0;
84 struct tty_struct * redirect = NULL;
85 struct wait_queue * keypress_wait = NULL;
86
87 static void initialize_tty_struct(struct tty_struct *tty);
88
89 static int tty_read(struct inode *, struct file *, char *, int);
90 static int tty_write(struct inode *, struct file *, char *, int);
91 static int tty_select(struct inode *, struct file *, int, select_table *);
92 static int tty_open(struct inode *, struct file *);
93 static void tty_release(struct inode *, struct file *);
94 static int tty_ioctl(struct inode * inode, struct file * file,
95 unsigned int cmd, unsigned long arg);
96 static int tty_fasync(struct inode * inode, struct file * filp, int on);
97
98 #ifndef MIN
99 #define MIN(a,b) ((a) < (b) ? (a) : (b))
100 #endif
101
102
103
104
105
106
107 char *_tty_name(struct tty_struct *tty, char *buf)
108 {
109 sprintf(buf, "%s%d", tty->driver.name,
110 MINOR(tty->device) - tty->driver.minor_start +
111 tty->driver.name_base);
112 return buf;
113 }
114
115 char *tty_name(struct tty_struct *tty)
116 {
117 static char buf[64];
118
119 return(_tty_name(tty, buf));
120 }
121
122 #define TTY_PARANOIA_CHECK
123
124 inline int tty_paranoia_check(struct tty_struct *tty, dev_t device,
125 const char *routine)
126 {
127 #ifdef TTY_PARANOIA_CHECK
128 static const char *badmagic =
129 "Warning: bad magic number for tty struct (%d, %d) in %s\n";
130 static const char *badtty =
131 "Warning: null TTY for (%d, %d) in %s\n";
132
133 if (!tty) {
134 printk(badtty, MAJOR(device), MINOR(device), routine);
135 return 1;
136 }
137 if (tty->magic != TTY_MAGIC) {
138 printk(badmagic, MAJOR(device), MINOR(device), routine);
139 return 1;
140 }
141 #endif
142 return 0;
143 }
144
145 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
146 {
147 if (disc < N_TTY || disc >= NR_LDISCS)
148 return -EINVAL;
149
150 if (new_ldisc) {
151 ldiscs[disc] = *new_ldisc;
152 ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
153 ldiscs[disc].num = disc;
154 } else
155 memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
156
157 return 0;
158 }
159
160
161 static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
162 {
163 int retval = 0;
164 struct tty_ldisc o_ldisc;
165
166 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS) ||
167 !(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED))
168 return -EINVAL;
169
170 if (tty->ldisc.num == ldisc)
171 return 0;
172 o_ldisc = tty->ldisc;
173
174
175 if (tty->ldisc.close)
176 (tty->ldisc.close)(tty);
177
178
179 tty->ldisc = ldiscs[ldisc];
180 tty->termios->c_line = ldisc;
181 if (tty->ldisc.open)
182 retval = (tty->ldisc.open)(tty);
183 if (retval < 0) {
184 tty->ldisc = o_ldisc;
185 tty->termios->c_line = tty->ldisc.num;
186 if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
187 tty->ldisc = ldiscs[N_TTY];
188 tty->termios->c_line = N_TTY;
189 if (tty->ldisc.open) {
190 int r = tty->ldisc.open(tty);
191
192 if (r < 0)
193 panic("Couldn't open N_TTY ldisc for "
194 "%s --- error %d.",
195 tty_name(tty), r);
196 }
197 }
198 }
199 if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc)
200 tty->driver.set_ldisc(tty);
201 return retval;
202 }
203
204
205
206
207 struct tty_driver *get_tty_driver(dev_t device)
208 {
209 int major, minor;
210 struct tty_driver *p;
211
212 minor = MINOR(device);
213 major = MAJOR(device);
214
215 for (p = tty_drivers; p; p = p->next) {
216 if (p->major != major)
217 continue;
218 if (minor < p->minor_start)
219 continue;
220 if (minor >= p->minor_start + p->num)
221 continue;
222 return p;
223 }
224 return NULL;
225 }
226
227
228
229
230
231
232 int tty_check_change(struct tty_struct * tty)
233 {
234 if (current->tty != tty)
235 return 0;
236 if (tty->pgrp <= 0) {
237 printk("tty_check_change: tty->pgrp <= 0!\n");
238 return 0;
239 }
240 if (current->pgrp == tty->pgrp)
241 return 0;
242 if (is_ignored(SIGTTOU))
243 return 0;
244 if (is_orphaned_pgrp(current->pgrp))
245 return -EIO;
246 (void) kill_pg(current->pgrp,SIGTTOU,1);
247 return -ERESTARTSYS;
248 }
249
250 static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
251 {
252 return 0;
253 }
254
255 static int hung_up_tty_write(struct inode * inode, struct file * file, char * buf, int count)
256 {
257 return -EIO;
258 }
259
260 static int hung_up_tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
261 {
262 return 1;
263 }
264
265 static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
266 unsigned int cmd, unsigned long arg)
267 {
268 return -EIO;
269 }
270
271 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
272 {
273 return -ESPIPE;
274 }
275
276 static struct file_operations tty_fops = {
277 tty_lseek,
278 tty_read,
279 tty_write,
280 NULL,
281 tty_select,
282 tty_ioctl,
283 NULL,
284 tty_open,
285 tty_release,
286 NULL,
287 tty_fasync
288 };
289
290 static struct file_operations hung_up_tty_fops = {
291 tty_lseek,
292 hung_up_tty_read,
293 hung_up_tty_write,
294 NULL,
295 hung_up_tty_select,
296 hung_up_tty_ioctl,
297 NULL,
298 NULL,
299 tty_release,
300 NULL,
301 NULL
302 };
303
304 void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
305 {
306 int i;
307 struct file * filp;
308 struct task_struct *p;
309
310 if (!tty)
311 return;
312 for (filp = first_file, i=0; i<nr_files; i++, filp = filp->f_next) {
313 if (!filp->f_count)
314 continue;
315 if (filp->private_data != tty)
316 continue;
317 if (filp->f_inode && filp->f_inode->i_rdev == CONSOLE_DEV)
318 continue;
319 if (filp->f_op != &tty_fops)
320 continue;
321 tty_fasync(filp->f_inode, filp, 0);
322 filp->f_op = fops;
323 }
324
325 if (tty->ldisc.flush_buffer)
326 tty->ldisc.flush_buffer(tty);
327 if (tty->driver.flush_buffer)
328 tty->driver.flush_buffer(tty);
329 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
330 tty->ldisc.write_wakeup)
331 (tty->ldisc.write_wakeup)(tty);
332 wake_up_interruptible(&tty->write_wait);
333 wake_up_interruptible(&tty->read_wait);
334
335
336
337
338
339 if (tty->ldisc.num != ldiscs[N_TTY].num) {
340 if (tty->ldisc.close)
341 (tty->ldisc.close)(tty);
342 tty->ldisc = ldiscs[N_TTY];
343 tty->termios->c_line = N_TTY;
344 if (tty->ldisc.open) {
345 i = (tty->ldisc.open)(tty);
346 if (i < 0)
347 printk("do_tty_hangup: N_TTY open: error %d\n",
348 -i);
349 }
350 }
351
352 if (tty->session > 0) {
353 kill_sl(tty->session,SIGHUP,1);
354 kill_sl(tty->session,SIGCONT,1);
355 }
356 tty->flags = 0;
357 tty->session = 0;
358 tty->pgrp = -1;
359 for_each_task(p) {
360 if (p->tty == tty)
361 p->tty = NULL;
362 }
363 if (tty->driver.hangup)
364 (tty->driver.hangup)(tty);
365 }
366
367 void tty_hangup(struct tty_struct * tty)
368 {
369 #ifdef TTY_DEBUG_HANGUP
370 printk("%s hangup...\n", tty_name(tty));
371 #endif
372 do_tty_hangup(tty, &hung_up_tty_fops);
373 }
374
375 void tty_vhangup(struct tty_struct * tty)
376 {
377 #ifdef TTY_DEBUG_HANGUP
378 printk("%s vhangup...\n", tty_name(tty));
379 #endif
380 do_tty_hangup(tty, &hung_up_tty_fops);
381 }
382
383 int tty_hung_up_p(struct file * filp)
384 {
385 return (filp->f_op == &hung_up_tty_fops);
386 }
387
388
389
390
391
392
393
394
395
396
397
398 void disassociate_ctty(int priv)
399 {
400 struct tty_struct *tty = current->tty;
401 struct task_struct *p;
402
403 if (!tty)
404 return;
405
406 if (tty->pgrp > 0) {
407 kill_pg(tty->pgrp, SIGHUP, priv);
408 kill_pg(tty->pgrp, SIGCONT, priv);
409 }
410 tty->session = 0;
411 tty->pgrp = -1;
412
413 for_each_task(p)
414 if (p->session == current->session)
415 p->tty = NULL;
416 }
417
418
419
420
421
422
423
424
425 static struct wait_queue *vt_activate_queue = NULL;
426
427
428
429
430
431 int vt_waitactive(void)
432 {
433 interruptible_sleep_on(&vt_activate_queue);
434 return (current->signal & ~current->blocked) ? -1 : 0;
435 }
436
437 #define vt_wake_waitactive() wake_up(&vt_activate_queue)
438
439 extern int kill_proc(int pid, int sig, int priv);
440
441
442
443
444 void complete_change_console(unsigned int new_console)
445 {
446 unsigned char old_vc_mode;
447
448 if (new_console == fg_console || new_console >= NR_CONSOLES)
449 return;
450
451
452
453
454
455
456 old_vc_mode = vt_cons[fg_console].vc_mode;
457 update_screen(new_console);
458
459
460
461
462
463
464 if (vt_cons[new_console].vt_mode.mode == VT_PROCESS)
465 {
466
467
468
469
470
471 if (kill_proc(vt_cons[new_console].vt_pid,
472 vt_cons[new_console].vt_mode.acqsig,
473 1) != 0)
474 {
475
476
477
478
479
480
481
482
483
484 vt_cons[new_console].vc_mode = KD_TEXT;
485 clr_vc_kbd_mode(kbd_table + new_console, VC_RAW);
486 clr_vc_kbd_mode(kbd_table + new_console, VC_MEDIUMRAW);
487 vt_cons[new_console].vt_mode.mode = VT_AUTO;
488 vt_cons[new_console].vt_mode.waitv = 0;
489 vt_cons[new_console].vt_mode.relsig = 0;
490 vt_cons[new_console].vt_mode.acqsig = 0;
491 vt_cons[new_console].vt_mode.frsig = 0;
492 vt_cons[new_console].vt_pid = -1;
493 vt_cons[new_console].vt_newvt = -1;
494 }
495 }
496
497
498
499
500
501 if (old_vc_mode != vt_cons[new_console].vc_mode)
502 {
503 if (vt_cons[new_console].vc_mode == KD_TEXT)
504 unblank_screen();
505 else {
506 timer_active &= ~(1<<BLANK_TIMER);
507 blank_screen();
508 }
509 }
510
511
512
513
514 vt_wake_waitactive();
515 return;
516 }
517
518
519
520
521 void change_console(unsigned int new_console)
522 {
523 if (new_console == fg_console || new_console >= NR_CONSOLES)
524 return;
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541 if (vt_cons[fg_console].vt_mode.mode == VT_PROCESS)
542 {
543
544
545
546
547
548 if (kill_proc(vt_cons[fg_console].vt_pid,
549 vt_cons[fg_console].vt_mode.relsig,
550 1) == 0)
551 {
552
553
554
555
556
557 vt_cons[fg_console].vt_newvt = new_console;
558 return;
559 }
560
561
562
563
564
565
566
567
568
569
570 vt_cons[fg_console].vc_mode = KD_TEXT;
571 clr_vc_kbd_mode(kbd_table + fg_console, VC_RAW);
572 clr_vc_kbd_mode(kbd_table + fg_console, VC_MEDIUMRAW);
573 vt_cons[fg_console].vt_mode.mode = VT_AUTO;
574 vt_cons[fg_console].vt_mode.waitv = 0;
575 vt_cons[fg_console].vt_mode.relsig = 0;
576 vt_cons[fg_console].vt_mode.acqsig = 0;
577 vt_cons[fg_console].vt_mode.frsig = 0;
578 vt_cons[fg_console].vt_pid = -1;
579 vt_cons[fg_console].vt_newvt = -1;
580
581
582
583 }
584
585
586
587
588 if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
589 return;
590
591 complete_change_console(new_console);
592 }
593
594 void wait_for_keypress(void)
595 {
596 sleep_on(&keypress_wait);
597 }
598
599 void stop_tty(struct tty_struct *tty)
600 {
601 if (tty->stopped)
602 return;
603 tty->stopped = 1;
604 if (tty->link && tty->link->packet) {
605 tty->ctrl_status &= ~TIOCPKT_START;
606 tty->ctrl_status |= TIOCPKT_STOP;
607 wake_up_interruptible(&tty->link->read_wait);
608 }
609 if (tty->driver.stop)
610 (tty->driver.stop)(tty);
611 }
612
613 void start_tty(struct tty_struct *tty)
614 {
615 if (!tty->stopped)
616 return;
617 tty->stopped = 0;
618 if (tty->link && tty->link->packet) {
619 tty->ctrl_status &= ~TIOCPKT_STOP;
620 tty->ctrl_status |= TIOCPKT_START;
621 wake_up_interruptible(&tty->link->read_wait);
622 }
623 if (tty->driver.start)
624 (tty->driver.start)(tty);
625 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
626 tty->ldisc.write_wakeup)
627 (tty->ldisc.write_wakeup)(tty);
628 wake_up_interruptible(&tty->write_wait);
629 }
630
631 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
632 {
633 int i;
634 struct tty_struct * tty;
635
636 tty = file->private_data;
637 if (tty_paranoia_check(tty, inode->i_rdev, "tty_read"))
638 return -EIO;
639 if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
640 return -EIO;
641
642
643
644
645
646 #if 0
647 if ((inode->i_rdev != CONSOLE_DEV) &&
648 (tty->pgrp > 0) &&
649 (current->tty == tty) &&
650 (tty->pgrp != current->pgrp))
651 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
652 return -EIO;
653 else {
654 (void) kill_pg(current->pgrp, SIGTTIN, 1);
655 return -ERESTARTSYS;
656 }
657 #endif
658 if (tty->ldisc.read)
659
660 i = (tty->ldisc.read)(tty,file,(unsigned char *)buf,(unsigned int)count);
661 else
662 i = -EIO;
663 if (i > 0)
664 inode->i_atime = CURRENT_TIME;
665 return i;
666 }
667
668 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
669 {
670 int i, is_console;
671 struct tty_struct * tty;
672
673 is_console = (inode->i_rdev == CONSOLE_DEV);
674
675 if (is_console && redirect)
676 tty = redirect;
677 else
678 tty = file->private_data;
679 if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
680 return -EIO;
681 if (!tty || !tty->driver.write || (tty->flags & (1 << TTY_IO_ERROR)))
682 return -EIO;
683 #if 0
684 if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
685 (current->tty == tty) && (tty->pgrp != current->pgrp)) {
686 if (is_orphaned_pgrp(current->pgrp))
687 return -EIO;
688 if (!is_ignored(SIGTTOU)) {
689 (void) kill_pg(current->pgrp, SIGTTOU, 1);
690 return -ERESTARTSYS;
691 }
692 }
693 #endif
694 if (tty->ldisc.write)
695
696 i = (tty->ldisc.write)(tty,file,(unsigned char *)buf,(unsigned int)count);
697 else
698 i = -EIO;
699 if (i > 0)
700 inode->i_mtime = CURRENT_TIME;
701 return i;
702 }
703
704
705
706
707
708
709 static int init_dev(dev_t device, struct tty_struct **ret_tty)
710 {
711 struct tty_struct *tty, **tty_loc, *o_tty, **o_tty_loc;
712 struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
713 struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
714 struct tty_driver *driver;
715 int retval;
716 int idx;
717
718 driver = get_tty_driver(device);
719 if (!driver)
720 return -ENODEV;
721
722 idx = MINOR(device) - driver->minor_start;
723 tty = o_tty = NULL;
724 tp = o_tp = NULL;
725 ltp = o_ltp = NULL;
726 o_tty_loc = NULL;
727 o_tp_loc = o_ltp_loc = NULL;
728
729 tty_loc = &driver->table[idx];
730 tp_loc = &driver->termios[idx];
731 ltp_loc = &driver->termios_locked[idx];
732
733 repeat:
734 retval = -EAGAIN;
735 if (driver->type == TTY_DRIVER_TYPE_PTY &&
736 driver->subtype == PTY_TYPE_MASTER &&
737 *tty_loc && (*tty_loc)->count)
738 goto end_init;
739 retval = -ENOMEM;
740 if (!*tty_loc && !tty) {
741 if (!(tty = (struct tty_struct*) get_free_page(GFP_KERNEL)))
742 goto end_init;
743 initialize_tty_struct(tty);
744 tty->device = device;
745 tty->driver = *driver;
746 goto repeat;
747 }
748 if (!*tp_loc && !tp) {
749 tp = (struct termios *) kmalloc(sizeof(struct termios),
750 GFP_KERNEL);
751 if (!tp)
752 goto end_init;
753 *tp = driver->init_termios;
754 goto repeat;
755 }
756 if (!*ltp_loc && !ltp) {
757 ltp = (struct termios *) kmalloc(sizeof(struct termios),
758 GFP_KERNEL);
759 if (!ltp)
760 goto end_init;
761 memset(ltp, 0, sizeof(struct termios));
762 goto repeat;
763 }
764 if (driver->type == TTY_DRIVER_TYPE_PTY) {
765 o_tty_loc = &driver->other->table[idx];
766 o_tp_loc = &driver->other->termios[idx];
767 o_ltp_loc = &driver->other->termios_locked[idx];
768
769 if (!*o_tty_loc && !o_tty) {
770 dev_t o_device;
771
772 o_tty = (struct tty_struct *)
773 get_free_page(GFP_KERNEL);
774 if (!o_tty)
775 goto end_init;
776 o_device = MKDEV(driver->other->major,
777 driver->other->minor_start + idx);
778 initialize_tty_struct(o_tty);
779 o_tty->device = o_device;
780 o_tty->driver = *driver->other;
781 goto repeat;
782 }
783 if (!*o_tp_loc && !o_tp) {
784 o_tp = (struct termios *)
785 kmalloc(sizeof(struct termios), GFP_KERNEL);
786 if (!o_tp)
787 goto end_init;
788 *o_tp = driver->other->init_termios;
789 goto repeat;
790 }
791 if (!*o_ltp_loc && !o_ltp) {
792 o_ltp = (struct termios *)
793 kmalloc(sizeof(struct termios), GFP_KERNEL);
794 if (!o_ltp)
795 goto end_init;
796 memset(o_ltp, 0, sizeof(struct termios));
797 goto repeat;
798 }
799
800 }
801
802 if (!*tp_loc) {
803 *tp_loc = tp;
804 tp = NULL;
805 }
806 if (!*ltp_loc) {
807 *ltp_loc = ltp;
808 ltp = NULL;
809 }
810 if (!*tty_loc) {
811 tty->termios = *tp_loc;
812 tty->termios_locked = *ltp_loc;
813 *tty_loc = tty;
814 (*driver->refcount)++;
815 (*tty_loc)->count++;
816 if (tty->ldisc.open) {
817 retval = (tty->ldisc.open)(tty);
818 if (retval < 0) {
819 (*tty_loc)->count--;
820 tty = NULL;
821 goto end_init;
822 }
823 }
824 tty = NULL;
825 } else
826 (*tty_loc)->count++;
827 if (driver->type == TTY_DRIVER_TYPE_PTY) {
828 if (!*o_tp_loc) {
829 *o_tp_loc = o_tp;
830 o_tp = NULL;
831 }
832 if (!*o_ltp_loc) {
833 *o_ltp_loc = o_ltp;
834 o_ltp = NULL;
835 }
836 if (!*o_tty_loc) {
837 o_tty->termios = *o_tp_loc;
838 o_tty->termios_locked = *o_ltp_loc;
839 *o_tty_loc = o_tty;
840 (*driver->other->refcount)++;
841 if (o_tty->ldisc.open) {
842 retval = (o_tty->ldisc.open)(o_tty);
843 if (retval < 0) {
844 (*tty_loc)->count--;
845 o_tty = NULL;
846 goto end_init;
847 }
848 }
849 o_tty = NULL;
850 }
851 (*tty_loc)->link = *o_tty_loc;
852 (*o_tty_loc)->link = *tty_loc;
853 if (driver->subtype == PTY_TYPE_MASTER)
854 (*o_tty_loc)->count++;
855 }
856 (*tty_loc)->driver = *driver;
857 *ret_tty = *tty_loc;
858 retval = 0;
859 end_init:
860 if (tty)
861 free_page((unsigned long) tty);
862 if (o_tty)
863 free_page((unsigned long) o_tty);
864 if (tp)
865 kfree_s(tp, sizeof(struct termios));
866 if (o_tp)
867 kfree_s(o_tp, sizeof(struct termios));
868 if (ltp)
869 kfree_s(ltp, sizeof(struct termios));
870 if (o_ltp)
871 kfree_s(o_ltp, sizeof(struct termios));
872 return retval;
873 }
874
875
876
877
878
879
880 static void release_dev(struct file * filp)
881 {
882 struct tty_struct *tty, *o_tty;
883 struct termios *tp, *o_tp, *ltp, *o_ltp;
884 struct task_struct **p;
885 int idx;
886
887
888 tty = filp->private_data;
889 if (tty_paranoia_check(tty, filp->f_inode->i_rdev, "release_dev"))
890 return;
891
892 tty_fasync(filp->f_inode, filp, 0);
893
894 tp = tty->termios;
895 ltp = tty->termios_locked;
896
897 idx = MINOR(tty->device) - tty->driver.minor_start;
898 #ifdef TTY_PARANOIA_CHECK
899 if (idx < 0 || idx >= tty->driver.num) {
900 printk("release_dev: bad idx when trying to free (%d, %d)\n",
901 MAJOR(tty->device), MINOR(tty->device));
902 return;
903 }
904 if (tty != tty->driver.table[idx]) {
905 printk("release_dev: driver.table[%d] not tty for (%d, %d)\n",
906 idx, MAJOR(tty->device), MINOR(tty->device));
907 return;
908 }
909 if (tp != tty->driver.termios[idx]) {
910 printk("release_dev: driver.termios[%d] not termios for (%d, %d)\n",
911 idx, MAJOR(tty->device), MINOR(tty->device));
912 return;
913 }
914 if (ltp != tty->driver.termios_locked[idx]) {
915 printk("release_dev: driver.termios_locked[%d] not termios_locked for (%d, %d)\n",
916 idx, MAJOR(tty->device), MINOR(tty->device));
917 return;
918 }
919 #endif
920
921 #ifdef TTY_DEBUG_HANGUP
922 printk("release_dev of %s (tty count=%d)...", tty_name(tty),
923 tty->count);
924 #endif
925
926 o_tty = tty->link;
927 o_tp = (o_tty) ? o_tty->termios : NULL;
928 o_ltp = (o_tty) ? o_tty->termios_locked : NULL;
929
930 #ifdef TTY_PARANOIA_CHECK
931 if (tty->driver.other) {
932 if (o_tty != tty->driver.other->table[idx]) {
933 printk("release_dev: other->table[%d] not o_tty for (%d, %d)\n",
934 idx, MAJOR(tty->device), MINOR(tty->device));
935 return;
936 }
937 if (o_tp != tty->driver.other->termios[idx]) {
938 printk("release_dev: other->termios[%d] not o_termios for (%d, %d)\n",
939 idx, MAJOR(tty->device), MINOR(tty->device));
940 return;
941 }
942 if (o_ltp != tty->driver.other->termios_locked[idx]) {
943 printk("release_dev: other->termios_locked[%d] not o_termios_locked for (%d, %d)\n",
944 idx, MAJOR(tty->device), MINOR(tty->device));
945 return;
946 }
947
948 if (o_tty->link != tty) {
949 printk("release_dev: bad pty pointers\n");
950 return;
951 }
952 }
953 #endif
954
955 if (tty->driver.close)
956 tty->driver.close(tty, filp);
957 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
958 tty->driver.subtype == PTY_TYPE_MASTER) {
959 if (--tty->link->count < 0) {
960 printk("release_dev: bad pty slave count (%d) for %s\n",
961 tty->count, tty_name(tty));
962 tty->link->count = 0;
963 }
964 }
965 if (--tty->count < 0) {
966 printk("release_dev: bad tty->count (%d) for %s\n",
967 tty->count, tty_name(tty));
968 tty->count = 0;
969 }
970 if (tty->count)
971 return;
972
973
974
975
976
977 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
978 if ((*p) && (*p)->tty == tty)
979 (*p)->tty = NULL;
980 }
981
982 if (o_tty) {
983 if (o_tty->count)
984 return;
985 tty->driver.other->table[idx] = NULL;
986 tty->driver.other->termios[idx] = NULL;
987 tty->driver.other->termios_locked[idx] = NULL;
988 }
989
990 #ifdef TTY_DEBUG_HANGUP
991 printk("freeing tty structure...");
992 #endif
993
994
995
996
997
998 if (tty->ldisc.close)
999 (tty->ldisc.close)(tty);
1000 tty->ldisc = ldiscs[N_TTY];
1001 tty->termios->c_line = N_TTY;
1002
1003 tty->driver.table[idx] = NULL;
1004 if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
1005 tty->driver.termios[idx] = NULL;
1006 tty->driver.termios_locked[idx] = NULL;
1007 kfree_s(tp, sizeof(struct termios));
1008 kfree_s(ltp, sizeof(struct termios));
1009 }
1010 if (tty == redirect || o_tty == redirect)
1011 redirect = NULL;
1012
1013
1014
1015
1016 cli();
1017 if (tty->flip.tqueue.sync) {
1018 struct tq_struct *tq, *prev;
1019
1020 for (tq=tq_timer, prev=0; tq; prev=tq, tq=tq->next) {
1021 if (tq == &tty->flip.tqueue) {
1022 if (prev)
1023 prev->next = tq->next;
1024 else
1025 tq_timer = tq->next;
1026 break;
1027 }
1028 }
1029 }
1030 sti();
1031 tty->magic = 0;
1032 (*tty->driver.refcount)--;
1033 free_page((unsigned long) tty);
1034 if (o_tty) {
1035 o_tty->magic = 0;
1036 (*o_tty->driver.refcount)--;
1037 free_page((unsigned long) o_tty);
1038 }
1039 if (o_tp)
1040 kfree_s(o_tp, sizeof(struct termios));
1041 if (o_ltp)
1042 kfree_s(o_ltp, sizeof(struct termios));
1043 }
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 static int tty_open(struct inode * inode, struct file * filp)
1058 {
1059 struct tty_struct *tty;
1060 int minor;
1061 int noctty, retval;
1062 dev_t device;
1063
1064 retry_open:
1065 noctty = filp->f_flags & O_NOCTTY;
1066 device = inode->i_rdev;
1067 if (device == TTY_DEV) {
1068 if (!current->tty)
1069 return -ENXIO;
1070 device = current->tty->device;
1071
1072 }
1073 if (device == CONSOLE_DEV) {
1074 device = MKDEV(TTY_MAJOR, fg_console+1);
1075 noctty = 1;
1076 }
1077 minor = MINOR(device);
1078
1079 retval = init_dev(device, &tty);
1080 filp->private_data = tty;
1081 if (retval)
1082 return retval;
1083 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1084 tty->driver.subtype == PTY_TYPE_MASTER)
1085 noctty = 1;
1086 #ifdef TTY_DEBUG_HANGUP
1087 printk("opening %s...", tty_name(tty));
1088 #endif
1089 if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
1090 retval = -EBUSY;
1091 else if (tty->driver.open)
1092 retval = tty->driver.open(tty, filp);
1093 else
1094 retval = -ENODEV;
1095
1096 if (retval) {
1097 #ifdef TTY_DEBUG_HANGUP
1098 printk("error %d in opening %s...", retval, tty_name(tty));
1099 #endif
1100
1101 release_dev(filp);
1102 if (retval != -ERESTARTSYS)
1103 return retval;
1104 if (current->signal & ~current->blocked)
1105 return retval;
1106 schedule();
1107
1108
1109
1110 filp->f_op = &tty_fops;
1111 goto retry_open;
1112 }
1113 if (!noctty &&
1114 current->leader &&
1115 !current->tty &&
1116 tty->session == 0) {
1117 current->tty = tty;
1118 tty->session = current->session;
1119 tty->pgrp = current->pgrp;
1120 }
1121 return 0;
1122 }
1123
1124
1125
1126
1127
1128
1129 static void tty_release(struct inode * inode, struct file * filp)
1130 {
1131 release_dev(filp);
1132 }
1133
1134 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
1135 {
1136 struct tty_struct * tty;
1137
1138 tty = filp->private_data;
1139 if (tty_paranoia_check(tty, inode->i_rdev, "tty_select"))
1140 return 0;
1141
1142 if (tty->ldisc.select)
1143 return (tty->ldisc.select)(tty, inode, filp, sel_type, wait);
1144 return 0;
1145 }
1146
1147 static int tty_fasync(struct inode * inode, struct file * filp, int on)
1148 {
1149 struct tty_struct * tty;
1150 struct fasync_struct *fa, *prev;
1151
1152 tty = filp->private_data;
1153 if (tty_paranoia_check(tty, inode->i_rdev, "tty_fasync"))
1154 return 0;
1155
1156 for (fa = tty->fasync, prev = 0; fa; prev= fa, fa = fa->fa_next) {
1157 if (fa->fa_file == filp)
1158 break;
1159 }
1160
1161 if (on) {
1162 if (fa)
1163 return 0;
1164 fa = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
1165 if (!fa)
1166 return -ENOMEM;
1167 fa->magic = FASYNC_MAGIC;
1168 fa->fa_file = filp;
1169 fa->fa_next = tty->fasync;
1170 tty->fasync = fa;
1171 if (!tty->read_wait)
1172 tty->minimum_to_wake = 1;
1173 } else {
1174 if (!fa)
1175 return 0;
1176 if (prev)
1177 prev->fa_next = fa->fa_next;
1178 else
1179 tty->fasync = fa->fa_next;
1180 kfree_s(fa, sizeof(struct fasync_struct));
1181 if (!tty->fasync && !tty->read_wait)
1182 tty->minimum_to_wake = N_TTY_BUF_SIZE;
1183 }
1184 return 0;
1185 }
1186
1187
1188
1189
1190 static int do_get_ps_info(int arg)
1191 {
1192 struct tstruct {
1193 int flag;
1194 int present[NR_TASKS];
1195 struct task_struct tasks[NR_TASKS];
1196 };
1197 struct tstruct *ts = (struct tstruct *)arg;
1198 struct task_struct **p;
1199 char *c, *d;
1200 int i, n = 0;
1201
1202 i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct tstruct));
1203 if (i)
1204 return i;
1205 for (p = &FIRST_TASK ; p <= &LAST_TASK ; p++, n++)
1206 if (*p)
1207 {
1208 c = (char *)(*p);
1209 d = (char *)(ts->tasks+n);
1210 for (i=0 ; i<sizeof(struct task_struct) ; i++)
1211 put_fs_byte(*c++, d++);
1212 put_fs_long(1, (unsigned long *)(ts->present+n));
1213 }
1214 else
1215 put_fs_long(0, (unsigned long *)(ts->present+n));
1216 return(0);
1217 }
1218
1219 static int tty_ioctl(struct inode * inode, struct file * file,
1220 unsigned int cmd, unsigned long arg)
1221 {
1222 int retval;
1223 struct tty_struct * tty;
1224 struct tty_struct * real_tty;
1225 struct winsize tmp_ws;
1226 pid_t pgrp;
1227 unsigned char ch;
1228 char mbz = 0;
1229
1230 tty = file->private_data;
1231 if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
1232 return -EINVAL;
1233
1234 if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
1235 tty->driver.subtype == PTY_TYPE_MASTER)
1236 real_tty = tty->link;
1237 else
1238 real_tty = tty;
1239
1240 switch (cmd) {
1241 case TIOCSTI:
1242 if ((current->tty != tty) && !suser())
1243 return -EPERM;
1244 ch = get_fs_byte((char *) arg);
1245 tty->ldisc.receive_buf(tty, &ch, &mbz, 1);
1246 return 0;
1247 case TIOCGWINSZ:
1248 retval = verify_area(VERIFY_WRITE, (void *) arg,
1249 sizeof (struct winsize));
1250 if (retval)
1251 return retval;
1252 memcpy_tofs((struct winsize *) arg, &tty->winsize,
1253 sizeof (struct winsize));
1254 return 0;
1255 case TIOCSWINSZ:
1256 memcpy_fromfs(&tmp_ws, (struct winsize *) arg,
1257 sizeof (struct winsize));
1258 if (memcmp(&tmp_ws, &tty->winsize,
1259 sizeof(struct winsize))) {
1260 if (tty->pgrp > 0)
1261 kill_pg(tty->pgrp, SIGWINCH, 1);
1262 if ((real_tty->pgrp != tty->pgrp) &&
1263 (real_tty->pgrp > 0))
1264 kill_pg(real_tty->pgrp, SIGWINCH, 1);
1265 }
1266 tty->winsize = tmp_ws;
1267 real_tty->winsize = tmp_ws;
1268 return 0;
1269 case TIOCCONS:
1270 if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) {
1271 if (!suser())
1272 return -EPERM;
1273 redirect = NULL;
1274 return 0;
1275 }
1276 if (redirect)
1277 return -EBUSY;
1278 redirect = real_tty;
1279 return 0;
1280 case FIONBIO:
1281 arg = get_fs_long((unsigned long *) arg);
1282 if (arg)
1283 file->f_flags |= O_NONBLOCK;
1284 else
1285 file->f_flags &= ~O_NONBLOCK;
1286 return 0;
1287 case TIOCEXCL:
1288 set_bit(TTY_EXCLUSIVE, &tty->flags);
1289 return 0;
1290 case TIOCNXCL:
1291 clear_bit(TTY_EXCLUSIVE, &tty->flags);
1292 return 0;
1293 case TIOCNOTTY:
1294 if (current->tty != tty)
1295 return -ENOTTY;
1296 if (current->leader)
1297 disassociate_ctty(0);
1298 current->tty = NULL;
1299 return 0;
1300 case TIOCSCTTY:
1301 if (current->leader &&
1302 (current->session == tty->session))
1303 return 0;
1304
1305
1306
1307
1308 if (!current->leader || current->tty)
1309 return -EPERM;
1310 if (tty->session > 0) {
1311
1312
1313
1314
1315 if ((arg == 1) && suser()) {
1316
1317
1318
1319 struct task_struct *p;
1320
1321 for_each_task(p)
1322 if (p->tty == tty)
1323 p->tty = NULL;
1324 } else
1325 return -EPERM;
1326 }
1327 current->tty = tty;
1328 tty->session = current->session;
1329 tty->pgrp = current->pgrp;
1330 return 0;
1331 case TIOCGPGRP:
1332
1333
1334
1335
1336 if (tty == real_tty && current->tty != real_tty)
1337 return -ENOTTY;
1338 retval = verify_area(VERIFY_WRITE, (void *) arg,
1339 sizeof (pid_t));
1340 if (retval)
1341 return retval;
1342 put_fs_long(real_tty->pgrp, (pid_t *) arg);
1343 return 0;
1344 case TIOCSPGRP:
1345 retval = tty_check_change(real_tty);
1346 if (retval)
1347 return retval;
1348 if (!current->tty ||
1349 (current->tty != real_tty) ||
1350 (real_tty->session != current->session))
1351 return -ENOTTY;
1352 pgrp = get_fs_long((pid_t *) arg);
1353 if (pgrp < 0)
1354 return -EINVAL;
1355 if (session_of_pgrp(pgrp) != current->session)
1356 return -EPERM;
1357 real_tty->pgrp = pgrp;
1358 return 0;
1359 case TIOCGETD:
1360 retval = verify_area(VERIFY_WRITE, (void *) arg,
1361 sizeof (unsigned long));
1362 if (retval)
1363 return retval;
1364 put_fs_long(tty->ldisc.num, (unsigned long *) arg);
1365 return 0;
1366 case TIOCSETD:
1367 retval = tty_check_change(tty);
1368 if (retval)
1369 return retval;
1370 arg = get_fs_long((unsigned long *) arg);
1371 return tty_set_ldisc(tty, arg);
1372 case TIOCLINUX:
1373 switch (get_fs_byte((char *)arg))
1374 {
1375 case 0:
1376 return do_screendump(arg);
1377 case 1:
1378 printk("Deprecated TIOCLINUX (1) ioctl\n");
1379 return do_get_ps_info(arg);
1380 #ifdef CONFIG_SELECTION
1381 case 2:
1382 return set_selection(arg);
1383 case 3:
1384 return paste_selection(tty);
1385 case 4:
1386 unblank_screen();
1387 return 0;
1388 #endif
1389 default:
1390 return -EINVAL;
1391 }
1392 default:
1393 if (tty->driver.ioctl) {
1394 retval = (tty->driver.ioctl)(tty, file,
1395 cmd, arg);
1396 if (retval != -ENOIOCTLCMD)
1397 return retval;
1398 }
1399 if (tty->ldisc.ioctl) {
1400 retval = (tty->ldisc.ioctl)(tty, file,
1401 cmd, arg);
1402 if (retval != -ENOIOCTLCMD)
1403 return retval;
1404 }
1405 return -EINVAL;
1406 }
1407 }
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422 void do_SAK( struct tty_struct *tty)
1423 {
1424 #ifdef TTY_SOFT_SAK
1425 tty_hangup(tty);
1426 #else
1427 struct task_struct **p;
1428 int session = tty->session;
1429 int i;
1430 struct file *filp;
1431
1432 if (tty->ldisc.flush_buffer)
1433 tty->ldisc.flush_buffer(tty);
1434 if (tty->driver.flush_buffer)
1435 tty->driver.flush_buffer(tty);
1436 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1437 if (!(*p))
1438 continue;
1439 if (((*p)->tty == tty) ||
1440 ((session > 0) && ((*p)->session == session)))
1441 send_sig(SIGKILL, *p, 1);
1442 else {
1443 for (i=0; i < NR_OPEN; i++) {
1444 filp = (*p)->files->fd[i];
1445 if (filp && (filp->f_op == &tty_fops) &&
1446 (filp->private_data == tty)) {
1447 send_sig(SIGKILL, *p, 1);
1448 break;
1449 }
1450 }
1451 }
1452 }
1453 #endif
1454 }
1455
1456
1457
1458
1459
1460 static void flush_to_ldisc(void *private)
1461 {
1462 struct tty_struct *tty = private;
1463 unsigned char *cp;
1464 char *fp;
1465 int count;
1466
1467 if (tty->flip.buf_num) {
1468 cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1469 fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1470 tty->flip.buf_num = 0;
1471
1472 cli();
1473 tty->flip.char_buf_ptr = tty->flip.char_buf;
1474 tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1475 } else {
1476 cp = tty->flip.char_buf;
1477 fp = tty->flip.flag_buf;
1478 tty->flip.buf_num = 1;
1479
1480 cli();
1481 tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
1482 tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
1483 }
1484 count = tty->flip.count;
1485 tty->flip.count = 0;
1486 sti();
1487
1488 #if 0
1489 if (count > tty->max_flip_cnt)
1490 tty->max_flip_cnt = count;
1491 #endif
1492 tty->ldisc.receive_buf(tty, cp, fp, count);
1493 }
1494
1495
1496
1497
1498 static void initialize_tty_struct(struct tty_struct *tty)
1499 {
1500 memset(tty, 0, sizeof(struct tty_struct));
1501 tty->magic = TTY_MAGIC;
1502 tty->ldisc = ldiscs[N_TTY];
1503 tty->pgrp = -1;
1504 tty->flip.char_buf_ptr = tty->flip.char_buf;
1505 tty->flip.flag_buf_ptr = tty->flip.flag_buf;
1506 tty->flip.tqueue.routine = flush_to_ldisc;
1507 tty->flip.tqueue.data = tty;
1508 }
1509
1510
1511
1512
1513 void tty_default_put_char(struct tty_struct *tty, unsigned char ch)
1514 {
1515 tty->driver.write(tty, 0, &ch, 1);
1516 }
1517
1518
1519
1520
1521 int tty_register_driver(struct tty_driver *driver)
1522 {
1523 if (driver->flags & TTY_DRIVER_INSTALLED)
1524 return 0;
1525
1526
1527
1528
1529 (void) register_chrdev(driver->major, driver->name, &tty_fops);
1530
1531 if (!driver->put_char)
1532 driver->put_char = tty_default_put_char;
1533
1534 driver->prev = 0;
1535 driver->next = tty_drivers;
1536 tty_drivers->prev = driver;
1537 tty_drivers = driver;
1538 return 0;
1539 }
1540
1541 long tty_init(long kmem_start)
1542 {
1543 if (sizeof(struct tty_struct) > PAGE_SIZE)
1544 panic("size of tty structure > PAGE_SIZE!");
1545 if (register_chrdev(TTY_MAJOR,"tty",&tty_fops))
1546 panic("unable to get major %d for tty device", TTY_MAJOR);
1547 if (register_chrdev(TTYAUX_MAJOR,"tty",&tty_fops))
1548 panic("unable to get major %d for tty device", TTYAUX_MAJOR);
1549 tty_drivers = 0;
1550
1551
1552 memset(ldiscs, 0, sizeof(ldiscs));
1553 (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1554
1555
1556
1557
1558
1559 memset(&tty_std_termios, 0, sizeof(struct termios));
1560 memcpy(tty_std_termios.c_cc, INIT_C_CC, NCCS);
1561 tty_std_termios.c_iflag = ICRNL | IXON;
1562 tty_std_termios.c_oflag = OPOST | ONLCR;
1563 tty_std_termios.c_cflag = B38400 | CS8 | CREAD;
1564 tty_std_termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
1565 ECHOCTL | ECHOKE | IEXTEN;
1566
1567 kmem_start = con_init(kmem_start);
1568 kmem_start = kbd_init(kmem_start);
1569 kmem_start = rs_init(kmem_start);
1570 kmem_start = pty_init(kmem_start);
1571 return kmem_start;
1572 }