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