This source file includes following definitions.
- tty_register_ldisc
- put_tty_queue
- get_tty_queue
- tty_read_raw_data
- tty_write_flush
- tty_read_flush
- 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
- opost
- echo_char
- eraser
- isig
- copy_to_cooked
- is_ignored
- input_available_p
- read_chan
- write_chan
- tty_read
- tty_write
- init_dev
- release_dev
- tty_open
- tty_release
- tty_select
- normal_select
- do_SAK
- tty_write_data
- tty_bh_routine
- initialize_tty_struct
- initialize_termios
- 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/tty.h>
47 #include <linux/timer.h>
48 #include <linux/ctype.h>
49 #include <linux/kd.h>
50 #include <linux/mm.h>
51 #include <linux/string.h>
52 #include <linux/malloc.h>
53
54 #include <asm/segment.h>
55 #include <asm/system.h>
56 #include <asm/bitops.h>
57
58 #include "kbd_kern.h"
59 #include "vt_kern.h"
60
61 #define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
62
63 #define MAX_TTYS 256
64
65 struct tty_struct *tty_table[MAX_TTYS];
66 struct termios *tty_termios[MAX_TTYS];
67
68 struct termios *termios_locked[MAX_TTYS];
69 struct tty_ldisc ldiscs[NR_LDISCS];
70 int tty_check_write[MAX_TTYS/32];
71
72
73
74
75
76
77 int fg_console = 0;
78 struct tty_struct * redirect = NULL;
79 struct wait_queue * keypress_wait = NULL;
80
81 static void initialize_tty_struct(int line, struct tty_struct *tty);
82 static void initialize_termios(int line, struct termios *tp);
83
84 static int tty_read(struct inode *, struct file *, char *, int);
85 static int tty_write(struct inode *, struct file *, char *, int);
86 static int tty_select(struct inode *, struct file *, int, select_table *);
87 static int tty_open(struct inode *, struct file *);
88 static void tty_release(struct inode *, struct file *);
89
90 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
91 {
92 if (disc < N_TTY || disc >= NR_LDISCS)
93 return -EINVAL;
94
95 if (new_ldisc) {
96 ldiscs[disc] = *new_ldisc;
97 ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
98 } else
99 memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
100
101 return 0;
102 }
103
104 void put_tty_queue(unsigned char c, struct tty_queue * queue)
105 {
106 int head;
107 unsigned long flags;
108
109 save_flags(flags);
110 cli();
111 head = (queue->head + 1) & (TTY_BUF_SIZE-1);
112 if (head != queue->tail) {
113 queue->buf[queue->head] = c;
114 queue->head = head;
115 }
116 restore_flags(flags);
117 }
118
119 int get_tty_queue(struct tty_queue * queue)
120 {
121 int result = -1;
122 unsigned long flags;
123
124 save_flags(flags);
125 cli();
126 if (queue->tail != queue->head) {
127 result = queue->buf[queue->tail];
128 INC(queue->tail);
129 }
130 restore_flags(flags);
131 return result;
132 }
133
134
135
136
137
138
139
140
141
142 int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen)
143 {
144 int result = 0;
145 unsigned char *p = bufp;
146 unsigned long flags;
147 int head, tail;
148 int ok = 1;
149
150 save_flags(flags);
151 cli();
152 tail = tty->read_q.tail;
153 head = tty->read_q.head;
154 while ((result < buflen) && (tail!=head) && ok) {
155 ok = !clear_bit (tail, &tty->readq_flags);
156 *p++ = tty->read_q.buf[tail++];
157 tail &= TTY_BUF_SIZE-1;
158 result++;
159 }
160 tty->read_q.tail = tail;
161 restore_flags(flags);
162 return (ok) ? result : -result;
163 }
164
165
166 void tty_write_flush(struct tty_struct * tty)
167 {
168 if (!tty->write || EMPTY(&tty->write_q))
169 return;
170 if (set_bit(TTY_WRITE_BUSY,&tty->flags))
171 return;
172 tty->write(tty);
173 if (!clear_bit(TTY_WRITE_BUSY,&tty->flags))
174 printk("tty_write_flush: bit already cleared\n");
175 }
176
177 void tty_read_flush(struct tty_struct * tty)
178 {
179 if (!tty || EMPTY(&tty->read_q))
180 return;
181 if (set_bit(TTY_READ_BUSY, &tty->flags))
182 return;
183 ldiscs[tty->disc].handler(tty);
184 if (!clear_bit(TTY_READ_BUSY, &tty->flags))
185 printk("tty_read_flush: bit already cleared\n");
186 }
187
188 static int hung_up_tty_read(struct inode * inode, struct file * file, char * buf, int count)
189 {
190 return 0;
191 }
192
193 static int hung_up_tty_write(struct inode * inode, struct file * file, char * buf, int count)
194 {
195 return -EIO;
196 }
197
198 static int hung_up_tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
199 {
200 return 1;
201 }
202
203 static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
204 unsigned int cmd, unsigned long arg)
205 {
206 return -EIO;
207 }
208
209 static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
210 {
211 return -ESPIPE;
212 }
213
214 static struct file_operations tty_fops = {
215 tty_lseek,
216 tty_read,
217 tty_write,
218 NULL,
219 tty_select,
220 tty_ioctl,
221 NULL,
222 tty_open,
223 tty_release
224 };
225
226 static struct file_operations hung_up_tty_fops = {
227 tty_lseek,
228 hung_up_tty_read,
229 hung_up_tty_write,
230 NULL,
231 hung_up_tty_select,
232 hung_up_tty_ioctl,
233 NULL,
234 NULL,
235 tty_release
236 };
237
238 void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
239 {
240 int i;
241 struct file * filp;
242 struct task_struct *p;
243 int dev;
244
245 if (!tty)
246 return;
247 dev = MKDEV(TTY_MAJOR,tty->line);
248 for (filp = first_file, i=0; i<nr_files; i++, filp = filp->f_next) {
249 if (!filp->f_count)
250 continue;
251 if (filp->f_rdev != dev)
252 continue;
253 if (filp->f_inode && filp->f_inode->i_rdev == CONSOLE_DEV)
254 continue;
255 if (filp->f_op != &tty_fops)
256 continue;
257 filp->f_op = fops;
258 }
259 flush_input(tty);
260 flush_output(tty);
261 wake_up_interruptible(&tty->secondary.proc_list);
262 if (tty->session > 0) {
263 kill_sl(tty->session,SIGHUP,1);
264 kill_sl(tty->session,SIGCONT,1);
265 }
266 tty->session = 0;
267 tty->pgrp = -1;
268 for_each_task(p) {
269 if (p->tty == tty->line)
270 p->tty = -1;
271 }
272 if (tty->hangup)
273 (tty->hangup)(tty);
274 }
275
276 void tty_hangup(struct tty_struct * tty)
277 {
278 #ifdef TTY_DEBUG_HANGUP
279 printk("tty%d hangup...\n", tty->line);
280 #endif
281 do_tty_hangup(tty, &hung_up_tty_fops);
282 }
283
284 void tty_vhangup(struct tty_struct * tty)
285 {
286 #ifdef TTY_DEBUG_HANGUP
287 printk("tty%d vhangup...\n", tty->line);
288 #endif
289 do_tty_hangup(tty, &hung_up_tty_fops);
290 }
291
292 int tty_hung_up_p(struct file * filp)
293 {
294 return (filp->f_op == &hung_up_tty_fops);
295 }
296
297
298
299
300
301
302
303
304
305
306
307 void disassociate_ctty(int priv)
308 {
309 struct tty_struct *tty;
310 struct task_struct *p;
311
312 if (current->tty >= 0) {
313 tty = tty_table[current->tty];
314 if (tty) {
315 if (tty->pgrp > 0) {
316 kill_pg(tty->pgrp, SIGHUP, priv);
317 kill_pg(tty->pgrp, SIGCONT, priv);
318 }
319 tty->session = 0;
320 tty->pgrp = -1;
321 } else
322 printk("disassociate_ctty: ctty is NULL?!?");
323 }
324
325 for_each_task(p)
326 if (p->session == current->session)
327 p->tty = -1;
328 }
329
330
331
332
333
334
335
336
337 static struct wait_queue *vt_activate_queue = NULL;
338
339
340
341
342
343 int vt_waitactive(void)
344 {
345 interruptible_sleep_on(&vt_activate_queue);
346 return (current->signal & ~current->blocked) ? -1 : 0;
347 }
348
349 #define vt_wake_waitactive() wake_up(&vt_activate_queue)
350
351 extern int kill_proc(int pid, int sig, int priv);
352
353
354
355
356 void complete_change_console(unsigned int new_console)
357 {
358 unsigned char old_vc_mode;
359
360 if (new_console == fg_console || new_console >= NR_CONSOLES)
361 return;
362
363
364
365
366
367
368 old_vc_mode = vt_cons[fg_console].vc_mode;
369 update_screen(new_console);
370
371
372
373
374
375
376 if (vt_cons[new_console].vt_mode.mode == VT_PROCESS)
377 {
378
379
380
381
382
383 if (kill_proc(vt_cons[new_console].vt_pid,
384 vt_cons[new_console].vt_mode.acqsig,
385 1) != 0)
386 {
387
388
389
390
391
392
393
394
395
396 vt_cons[new_console].vc_mode = KD_TEXT;
397 clr_vc_kbd_mode(kbd_table + new_console, VC_RAW);
398 clr_vc_kbd_mode(kbd_table + new_console, VC_MEDIUMRAW);
399 vt_cons[new_console].vt_mode.mode = VT_AUTO;
400 vt_cons[new_console].vt_mode.waitv = 0;
401 vt_cons[new_console].vt_mode.relsig = 0;
402 vt_cons[new_console].vt_mode.acqsig = 0;
403 vt_cons[new_console].vt_mode.frsig = 0;
404 vt_cons[new_console].vt_pid = -1;
405 vt_cons[new_console].vt_newvt = -1;
406 }
407 }
408
409
410
411
412
413 if (old_vc_mode != vt_cons[new_console].vc_mode)
414 {
415 if (vt_cons[new_console].vc_mode == KD_TEXT)
416 unblank_screen();
417 else {
418 timer_active &= ~(1<<BLANK_TIMER);
419 blank_screen();
420 }
421 }
422
423
424
425
426 vt_wake_waitactive();
427 return;
428 }
429
430
431
432
433 void change_console(unsigned int new_console)
434 {
435 if (new_console == fg_console || new_console >= NR_CONSOLES)
436 return;
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453 if (vt_cons[fg_console].vt_mode.mode == VT_PROCESS)
454 {
455
456
457
458
459
460 if (kill_proc(vt_cons[fg_console].vt_pid,
461 vt_cons[fg_console].vt_mode.relsig,
462 1) == 0)
463 {
464
465
466
467
468
469 vt_cons[fg_console].vt_newvt = new_console;
470 return;
471 }
472
473
474
475
476
477
478
479
480
481
482 vt_cons[fg_console].vc_mode = KD_TEXT;
483 clr_vc_kbd_mode(kbd_table + fg_console, VC_RAW);
484 clr_vc_kbd_mode(kbd_table + fg_console, VC_MEDIUMRAW);
485 vt_cons[fg_console].vt_mode.mode = VT_AUTO;
486 vt_cons[fg_console].vt_mode.waitv = 0;
487 vt_cons[fg_console].vt_mode.relsig = 0;
488 vt_cons[fg_console].vt_mode.acqsig = 0;
489 vt_cons[fg_console].vt_mode.frsig = 0;
490 vt_cons[fg_console].vt_pid = -1;
491 vt_cons[fg_console].vt_newvt = -1;
492
493
494
495 }
496
497
498
499
500 if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
501 return;
502
503 complete_change_console(new_console);
504 }
505
506 void wait_for_keypress(void)
507 {
508 sleep_on(&keypress_wait);
509 }
510
511 void stop_tty(struct tty_struct *tty)
512 {
513 if (tty->stopped)
514 return;
515 tty->stopped = 1;
516 if (tty->link && tty->link->packet) {
517 tty->ctrl_status &= ~TIOCPKT_START;
518 tty->ctrl_status |= TIOCPKT_STOP;
519 wake_up_interruptible(&tty->link->secondary.proc_list);
520 }
521 if (tty->stop)
522 (tty->stop)(tty);
523 if (IS_A_CONSOLE(tty->line)) {
524 set_vc_kbd_led(kbd_table + fg_console, VC_SCROLLOCK);
525 set_leds();
526 }
527 }
528
529 void start_tty(struct tty_struct *tty)
530 {
531 if (!tty->stopped)
532 return;
533 tty->stopped = 0;
534 if (tty->link && tty->link->packet) {
535 tty->ctrl_status &= ~TIOCPKT_STOP;
536 tty->ctrl_status |= TIOCPKT_START;
537 wake_up_interruptible(&tty->link->secondary.proc_list);
538 }
539 if (tty->start)
540 (tty->start)(tty);
541 TTY_WRITE_FLUSH(tty);
542 if (IS_A_CONSOLE(tty->line)) {
543 clr_vc_kbd_led(kbd_table + fg_console, VC_SCROLLOCK);
544 set_leds();
545 }
546 }
547
548
549
550
551 static int opost(unsigned char c, struct tty_struct *tty)
552 {
553 if (FULL(&tty->write_q))
554 return -1;
555 if (O_OPOST(tty)) {
556 switch (c) {
557 case '\n':
558 if (O_ONLRET(tty))
559 tty->column = 0;
560 if (O_ONLCR(tty)) {
561 if (LEFT(&tty->write_q) < 2)
562 return -1;
563 put_tty_queue('\r', &tty->write_q);
564 tty->column = 0;
565 }
566 tty->canon_column = tty->column;
567 break;
568 case '\r':
569 if (O_ONOCR(tty) && tty->column == 0)
570 return 0;
571 if (O_OCRNL(tty)) {
572 c = '\n';
573 if (O_ONLRET(tty))
574 tty->canon_column = tty->column = 0;
575 break;
576 }
577 tty->canon_column = tty->column = 0;
578 break;
579 case '\t':
580 if (O_TABDLY(tty) == XTABS) {
581 if (LEFT(&tty->write_q) < 8)
582 return -1;
583 do
584 put_tty_queue(' ', &tty->write_q);
585 while (++tty->column % 8);
586 return 0;
587 }
588 tty->column = (tty->column | 7) + 1;
589 break;
590 case '\b':
591 if (tty->column > 0)
592 tty->column--;
593 break;
594 default:
595 if (O_OLCUC(tty))
596 c = toupper(c);
597 if (!iscntrl(c))
598 tty->column++;
599 break;
600 }
601 }
602 put_tty_queue(c, &tty->write_q);
603 return 0;
604 }
605
606
607
608 static void echo_char(unsigned char c, struct tty_struct *tty)
609 {
610 if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') {
611 opost('^', tty);
612 opost(c ^ 0100, tty);
613 } else
614 opost(c, tty);
615 }
616
617 static void eraser(unsigned char c, struct tty_struct *tty)
618 {
619 enum { ERASE, WERASE, KILL } kill_type;
620 int seen_alnums;
621
622 if (tty->secondary.head == tty->canon_head) {
623
624 return;
625 }
626 if (c == ERASE_CHAR(tty))
627 kill_type = ERASE;
628 else if (c == WERASE_CHAR(tty))
629 kill_type = WERASE;
630 else {
631 if (!L_ECHO(tty)) {
632 tty->secondary.head = tty->canon_head;
633 return;
634 }
635 if (!L_ECHOK(tty) || !L_ECHOKE(tty)) {
636 tty->secondary.head = tty->canon_head;
637 if (tty->erasing) {
638 opost('/', tty);
639 tty->erasing = 0;
640 }
641 echo_char(KILL_CHAR(tty), tty);
642
643 if (L_ECHOK(tty))
644 opost('\n', tty);
645 return;
646 }
647 kill_type = KILL;
648 }
649
650 seen_alnums = 0;
651 while (tty->secondary.head != tty->canon_head) {
652 c = LAST(&tty->secondary);
653 if (kill_type == WERASE) {
654
655 if (isalnum(c) || c == '_')
656 seen_alnums++;
657 else if (seen_alnums)
658 break;
659 }
660 DEC(tty->secondary.head);
661 if (L_ECHO(tty)) {
662 if (L_ECHOPRT(tty)) {
663 if (!tty->erasing) {
664 opost('\\', tty);
665 tty->erasing = 1;
666 }
667 echo_char(c, tty);
668 } else if (!L_ECHOE(tty)) {
669 echo_char(ERASE_CHAR(tty), tty);
670 } else if (c == '\t') {
671 unsigned int col = tty->canon_column;
672 unsigned long tail = tty->canon_head;
673
674
675 while (tail != tty->secondary.head) {
676 c = tty->secondary.buf[tail];
677 if (c == '\t')
678 col = (col | 7) + 1;
679 else if (iscntrl(c)) {
680 if (L_ECHOCTL(tty))
681 col += 2;
682 } else
683 col++;
684 INC(tail);
685 }
686
687
688 while (tty->column > col) {
689
690 put_tty_queue('\b', &tty->write_q);
691 tty->column--;
692 }
693 } else {
694 if (iscntrl(c) && L_ECHOCTL(tty)) {
695 opost('\b', tty);
696 opost(' ', tty);
697 opost('\b', tty);
698 }
699 if (!iscntrl(c) || L_ECHOCTL(tty)) {
700 opost('\b', tty);
701 opost(' ', tty);
702 opost('\b', tty);
703 }
704 }
705 }
706 if (kill_type == ERASE)
707 break;
708 }
709 if (tty->erasing && tty->secondary.head == tty->canon_head) {
710 opost('/', tty);
711 tty->erasing = 0;
712 }
713 }
714
715 static void isig(int sig, struct tty_struct *tty)
716 {
717 kill_pg(tty->pgrp, sig, 1);
718 if (!L_NOFLSH(tty)) {
719 flush_input(tty);
720 flush_output(tty);
721 }
722 }
723
724 static void copy_to_cooked(struct tty_struct * tty)
725 {
726 int c, special_flag;
727 unsigned long flags;
728
729 if (!tty) {
730 printk("copy_to_cooked: called with NULL tty\n");
731 return;
732 }
733 if (!tty->write) {
734 printk("copy_to_cooked: tty %d has null write routine\n",
735 tty->line);
736 }
737 while (1) {
738
739
740
741
742
743 c = LEFT(&tty->secondary);
744 if (tty->throttle && (c < SQ_THRESHOLD_LW)
745 && !set_bit(TTY_SQ_THROTTLED, &tty->flags))
746 tty->throttle(tty, TTY_THROTTLE_SQ_FULL);
747 if (c == 0)
748 break;
749 save_flags(flags); cli();
750 if (!EMPTY(&tty->read_q)) {
751 c = tty->read_q.buf[tty->read_q.tail];
752 special_flag = clear_bit(tty->read_q.tail,
753 &tty->readq_flags);
754 INC(tty->read_q.tail);
755 restore_flags(flags);
756 } else {
757 restore_flags(flags);
758 break;
759 }
760 if (special_flag) {
761 tty->char_error = c;
762 continue;
763 }
764 if (tty->char_error) {
765 if (tty->char_error == TTY_BREAK) {
766 tty->char_error = 0;
767 if (I_IGNBRK(tty))
768 continue;
769
770 if (I_BRKINT(tty))
771 continue;
772 if (I_PARMRK(tty)) {
773 put_tty_queue('\377', &tty->secondary);
774 put_tty_queue('\0', &tty->secondary);
775 }
776 put_tty_queue('\0', &tty->secondary);
777 continue;
778 }
779 if (tty->char_error == TTY_OVERRUN) {
780 tty->char_error = 0;
781 printk("tty%d: input overrun\n", tty->line);
782 continue;
783 }
784
785 tty->char_error = 0;
786 if (I_IGNPAR(tty)) {
787 continue;
788 }
789 if (I_PARMRK(tty)) {
790 put_tty_queue('\377', &tty->secondary);
791 put_tty_queue('\0', &tty->secondary);
792 put_tty_queue(c, &tty->secondary);
793 } else
794 put_tty_queue('\0', &tty->secondary);
795 continue;
796 }
797 if (I_ISTRIP(tty))
798 c &= 0x7f;
799 if (!tty->lnext) {
800 if (c == '\r') {
801 if (I_IGNCR(tty))
802 continue;
803 if (I_ICRNL(tty))
804 c = '\n';
805 } else if (c == '\n' && I_INLCR(tty))
806 c = '\r';
807 }
808 if (I_IUCLC(tty) && L_IEXTEN(tty))
809 c=tolower(c);
810 if (c == __DISABLED_CHAR)
811 tty->lnext = 1;
812 if (L_ICANON(tty) && !tty->lnext) {
813 if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
814 (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
815 eraser(c, tty);
816 continue;
817 }
818 if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
819 tty->lnext = 1;
820 if (L_ECHO(tty)) {
821 if (tty->erasing) {
822 opost('/', tty);
823 tty->erasing = 0;
824 }
825 if (L_ECHOCTL(tty)) {
826 opost('^', tty);
827 opost('\b', tty);
828 }
829 }
830 continue;
831 }
832 if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
833 L_IEXTEN(tty)) {
834 unsigned long tail = tty->canon_head;
835
836 if (tty->erasing) {
837 opost('/', tty);
838 tty->erasing = 0;
839 }
840 echo_char(c, tty);
841 opost('\n', tty);
842 while (tail != tty->secondary.head) {
843 echo_char(tty->secondary.buf[tail],
844 tty);
845 INC(tail);
846 }
847 continue;
848 }
849 }
850 if (I_IXON(tty) && !tty->lnext) {
851 if ((tty->stopped && I_IXANY(tty) && L_IEXTEN(tty)) ||
852 c == START_CHAR(tty)) {
853 start_tty(tty);
854 continue;
855 }
856 if (c == STOP_CHAR(tty)) {
857 stop_tty(tty);
858 continue;
859 }
860 }
861 if (L_ISIG(tty) && !tty->lnext) {
862 if (c == INTR_CHAR(tty)) {
863 isig(SIGINT, tty);
864 continue;
865 }
866 if (c == QUIT_CHAR(tty)) {
867 isig(SIGQUIT, tty);
868 continue;
869 }
870 if (c == SUSP_CHAR(tty)) {
871 if (!is_orphaned_pgrp(tty->pgrp))
872 isig(SIGTSTP, tty);
873 continue;
874 }
875 }
876
877 if (tty->erasing) {
878 opost('/', tty);
879 tty->erasing = 0;
880 }
881 if (c == '\n' && !tty->lnext) {
882 if (L_ECHO(tty) || (L_ICANON(tty) && L_ECHONL(tty)))
883 opost('\n', tty);
884 } else if (L_ECHO(tty)) {
885
886
887
888 if (c != EOF_CHAR(tty) || !L_ICANON(tty) ||
889 tty->lnext) {
890
891 if (tty->canon_head == tty->secondary.head)
892 tty->canon_column = tty->column;
893 echo_char(c, tty);
894 }
895 }
896
897 if (I_PARMRK(tty) && c == (unsigned char) '\377' &&
898 (c != EOF_CHAR(tty) || !L_ICANON(tty) || tty->lnext))
899 put_tty_queue(c, &tty->secondary);
900
901 if (L_ICANON(tty) && !tty->lnext &&
902 (c == '\n' || c == EOF_CHAR(tty) || c == EOL_CHAR(tty) ||
903 (c == EOL2_CHAR(tty) && L_IEXTEN(tty)))) {
904 if (c == EOF_CHAR(tty))
905 c = __DISABLED_CHAR;
906 set_bit(tty->secondary.head, &tty->secondary_flags);
907 put_tty_queue(c, &tty->secondary);
908 tty->canon_head = tty->secondary.head;
909 tty->canon_data++;
910 } else
911 put_tty_queue(c, &tty->secondary);
912 tty->lnext = 0;
913 }
914 if (!EMPTY(&tty->write_q))
915 TTY_WRITE_FLUSH(tty);
916 if (L_ICANON(tty) ? tty->canon_data : !EMPTY(&tty->secondary))
917 wake_up_interruptible(&tty->secondary.proc_list);
918
919 if (tty->throttle && (LEFT(&tty->read_q) >= RQ_THRESHOLD_HW)
920 && clear_bit(TTY_RQ_THROTTLED, &tty->flags))
921 tty->throttle(tty, TTY_THROTTLE_RQ_AVAIL);
922 }
923
924 int is_ignored(int sig)
925 {
926 return ((current->blocked & (1<<(sig-1))) ||
927 (current->sigaction[sig-1].sa_handler == SIG_IGN));
928 }
929
930 static inline int input_available_p(struct tty_struct *tty)
931 {
932
933 if (L_ICANON(tty) ? tty->canon_data : !EMPTY(&tty->secondary))
934 return 1;
935
936
937 TTY_READ_FLUSH(tty);
938 if (tty->link)
939 TTY_WRITE_FLUSH(tty->link);
940
941 if (L_ICANON(tty) ? tty->canon_data : !EMPTY(&tty->secondary))
942 return 1;
943 return 0;
944 }
945
946 static int read_chan(struct tty_struct *tty, struct file *file,
947 unsigned char *buf, unsigned int nr)
948 {
949 struct wait_queue wait = { current, NULL };
950 int c;
951 unsigned char *b = buf;
952 int minimum, time;
953 int retval = 0;
954
955
956
957
958
959
960 if (file->f_inode->i_rdev != CONSOLE_DEV &&
961 current->tty == tty->line) {
962 if (tty->pgrp <= 0)
963 printk("read_chan: tty->pgrp <= 0!\n");
964 else if (current->pgrp != tty->pgrp) {
965 if (is_ignored(SIGTTIN) ||
966 is_orphaned_pgrp(current->pgrp))
967 return -EIO;
968 kill_pg(current->pgrp, SIGTTIN, 1);
969 return -ERESTARTSYS;
970 }
971 }
972
973 if (L_ICANON(tty)) {
974 minimum = time = 0;
975 current->timeout = (unsigned long) -1;
976 } else {
977 time = (HZ / 10) * TIME_CHAR(tty);
978 minimum = MIN_CHAR(tty);
979 if (minimum)
980 current->timeout = (unsigned long) -1;
981 else {
982 if (time) {
983 current->timeout = time + jiffies;
984 time = 0;
985 } else
986 current->timeout = 0;
987 minimum = 1;
988 }
989 }
990
991 add_wait_queue(&tty->secondary.proc_list, &wait);
992 while (1) {
993
994 if (tty->packet && tty->link->ctrl_status) {
995 if (b != buf)
996 break;
997 put_fs_byte(tty->link->ctrl_status, b++);
998 tty->link->ctrl_status = 0;
999 break;
1000 }
1001
1002
1003
1004 current->state = TASK_INTERRUPTIBLE;
1005 if (!input_available_p(tty)) {
1006 if (tty->flags & (1 << TTY_SLAVE_CLOSED)) {
1007 retval = -EIO;
1008 break;
1009 }
1010 if (tty_hung_up_p(file))
1011 break;
1012 if (!current->timeout)
1013 break;
1014 if (file->f_flags & O_NONBLOCK) {
1015 retval = -EAGAIN;
1016 break;
1017 }
1018 if (current->signal & ~current->blocked) {
1019 retval = -ERESTARTSYS;
1020 break;
1021 }
1022 schedule();
1023 continue;
1024 }
1025 current->state = TASK_RUNNING;
1026
1027
1028 if (tty->packet && b == buf) {
1029 put_fs_byte(TIOCPKT_DATA, b++);
1030 nr--;
1031 }
1032
1033 while (1) {
1034 int eol;
1035
1036 cli();
1037 if (EMPTY(&tty->secondary)) {
1038 sti();
1039 break;
1040 }
1041 eol = clear_bit(tty->secondary.tail,
1042 &tty->secondary_flags);
1043 c = tty->secondary.buf[tty->secondary.tail];
1044 if (!nr) {
1045
1046
1047
1048
1049
1050 if (eol) {
1051 if (c == __DISABLED_CHAR) {
1052 tty->canon_data--;
1053 INC(tty->secondary.tail);
1054 } else {
1055 set_bit(tty->secondary.tail,
1056 &tty->secondary_flags);
1057 }
1058 }
1059 sti();
1060 break;
1061 }
1062 INC(tty->secondary.tail);
1063 sti();
1064 if (eol) {
1065 if (--tty->canon_data < 0) {
1066 printk("read_chan: canon_data < 0!\n");
1067 tty->canon_data = 0;
1068 }
1069 if (c == __DISABLED_CHAR)
1070 break;
1071 put_fs_byte(c, b++);
1072 nr--;
1073 break;
1074 }
1075 put_fs_byte(c, b++);
1076 nr--;
1077 }
1078
1079
1080
1081 if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
1082 && clear_bit(TTY_SQ_THROTTLED, &tty->flags))
1083 tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
1084
1085 if (b - buf >= minimum || !nr)
1086 break;
1087 if (time)
1088 current->timeout = time + jiffies;
1089 }
1090 remove_wait_queue(&tty->secondary.proc_list, &wait);
1091 current->state = TASK_RUNNING;
1092 current->timeout = 0;
1093 return (b - buf) ? b - buf : retval;
1094 }
1095
1096 static int write_chan(struct tty_struct * tty, struct file * file,
1097 unsigned char * buf, unsigned int nr)
1098 {
1099 struct wait_queue wait = { current, NULL };
1100 int c;
1101 unsigned char *b = buf;
1102 int retval = 0;
1103
1104
1105 if (L_TOSTOP(tty) && file->f_inode->i_rdev != CONSOLE_DEV) {
1106 retval = check_change(tty, tty->line);
1107 if (retval)
1108 return retval;
1109 }
1110
1111 add_wait_queue(&tty->write_q.proc_list, &wait);
1112 while (1) {
1113 current->state = TASK_INTERRUPTIBLE;
1114 if (current->signal & ~current->blocked) {
1115 retval = -ERESTARTSYS;
1116 break;
1117 }
1118 if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
1119 retval = -EIO;
1120 break;
1121 }
1122 while (nr > 0) {
1123 c = get_fs_byte(b);
1124
1125
1126 if (opost(c, tty) < 0)
1127 break;
1128 b++; nr--;
1129 }
1130 TTY_WRITE_FLUSH(tty);
1131 if (!nr)
1132 break;
1133 if (EMPTY(&tty->write_q) && !need_resched)
1134 continue;
1135 if (file->f_flags & O_NONBLOCK) {
1136 retval = -EAGAIN;
1137 break;
1138 }
1139 schedule();
1140 }
1141 current->state = TASK_RUNNING;
1142 remove_wait_queue(&tty->write_q.proc_list, &wait);
1143 return (b - buf) ? b - buf : retval;
1144 }
1145
1146 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
1147 {
1148 int i, dev;
1149 struct tty_struct * tty;
1150
1151 dev = file->f_rdev;
1152 if (MAJOR(dev) != TTY_MAJOR) {
1153 printk("tty_read: bad pseudo-major nr #%d\n", MAJOR(dev));
1154 return -EINVAL;
1155 }
1156 dev = MINOR(dev);
1157 tty = TTY_TABLE(dev);
1158 if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
1159 return -EIO;
1160
1161
1162
1163
1164
1165 #if 0
1166 if ((inode->i_rdev != CONSOLE_DEV) &&
1167 (tty->pgrp > 0) &&
1168 (current->tty == dev) &&
1169 (tty->pgrp != current->pgrp))
1170 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
1171 return -EIO;
1172 else {
1173 (void) kill_pg(current->pgrp, SIGTTIN, 1);
1174 return -ERESTARTSYS;
1175 }
1176 #endif
1177 if (ldiscs[tty->disc].read)
1178
1179 i = (ldiscs[tty->disc].read)(tty,file,(unsigned char *)buf,(unsigned int)count);
1180 else
1181 i = -EIO;
1182 if (i > 0)
1183 inode->i_atime = CURRENT_TIME;
1184 return i;
1185 }
1186
1187 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
1188 {
1189 int dev, i, is_console;
1190 struct tty_struct * tty;
1191
1192 dev = file->f_rdev;
1193 is_console = (inode->i_rdev == CONSOLE_DEV);
1194 if (MAJOR(dev) != TTY_MAJOR) {
1195 printk("tty_write: pseudo-major != TTY_MAJOR\n");
1196 return -EINVAL;
1197 }
1198 dev = MINOR(dev);
1199 if (is_console && redirect)
1200 tty = redirect;
1201 else
1202 tty = TTY_TABLE(dev);
1203 if (!tty || !tty->write || (tty->flags & (1 << TTY_IO_ERROR)))
1204 return -EIO;
1205 #if 0
1206 if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
1207 (current->tty == dev) && (tty->pgrp != current->pgrp)) {
1208 if (is_orphaned_pgrp(current->pgrp))
1209 return -EIO;
1210 if (!is_ignored(SIGTTOU)) {
1211 (void) kill_pg(current->pgrp, SIGTTOU, 1);
1212 return -ERESTARTSYS;
1213 }
1214 }
1215 #endif
1216 if (ldiscs[tty->disc].write)
1217
1218 i = (ldiscs[tty->disc].write)(tty,file,(unsigned char *)buf,(unsigned int)count);
1219 else
1220 i = -EIO;
1221 if (i > 0)
1222 inode->i_mtime = CURRENT_TIME;
1223 return i;
1224 }
1225
1226
1227
1228
1229
1230
1231 static int init_dev(int dev)
1232 {
1233 struct tty_struct *tty, *o_tty;
1234 struct termios *tp, *o_tp, *ltp, *o_ltp;
1235 int retval;
1236 int o_dev;
1237
1238 o_dev = PTY_OTHER(dev);
1239 tty = o_tty = NULL;
1240 tp = o_tp = NULL;
1241 ltp = o_ltp = NULL;
1242 repeat:
1243 retval = -EAGAIN;
1244 if (IS_A_PTY_MASTER(dev) && tty_table[dev] && tty_table[dev]->count)
1245 goto end_init;
1246 retval = -ENOMEM;
1247 if (!tty_table[dev] && !tty) {
1248 if (!(tty = (struct tty_struct*) get_free_page(GFP_KERNEL)))
1249 goto end_init;
1250 initialize_tty_struct(dev, tty);
1251 goto repeat;
1252 }
1253 if (!tty_termios[dev] && !tp) {
1254 tp = (struct termios *) kmalloc(sizeof(struct termios),
1255 GFP_KERNEL);
1256 if (!tp)
1257 goto end_init;
1258 initialize_termios(dev, tp);
1259 goto repeat;
1260 }
1261 if (!termios_locked[dev] && !ltp) {
1262 ltp = (struct termios *) kmalloc(sizeof(struct termios),
1263 GFP_KERNEL);
1264 if (!ltp)
1265 goto end_init;
1266 memset(ltp, 0, sizeof(struct termios));
1267 goto repeat;
1268 }
1269 if (IS_A_PTY(dev)) {
1270 if (!tty_table[o_dev] && !o_tty) {
1271 o_tty = (struct tty_struct *)
1272 get_free_page(GFP_KERNEL);
1273 if (!o_tty)
1274 goto end_init;
1275 initialize_tty_struct(o_dev, o_tty);
1276 goto repeat;
1277 }
1278 if (!tty_termios[o_dev] && !o_tp) {
1279 o_tp = (struct termios *)
1280 kmalloc(sizeof(struct termios), GFP_KERNEL);
1281 if (!o_tp)
1282 goto end_init;
1283 initialize_termios(o_dev, o_tp);
1284 goto repeat;
1285 }
1286 if (!termios_locked[o_dev] && !o_ltp) {
1287 o_ltp = (struct termios *)
1288 kmalloc(sizeof(struct termios), GFP_KERNEL);
1289 if (!o_ltp)
1290 goto end_init;
1291 memset(o_ltp, 0, sizeof(struct termios));
1292 goto repeat;
1293 }
1294
1295 }
1296
1297 if (!tty_termios[dev]) {
1298 tty_termios[dev] = tp;
1299 tp = NULL;
1300 }
1301 if (!tty_table[dev]) {
1302 tty->termios = tty_termios[dev];
1303 tty_table[dev] = tty;
1304 tty = NULL;
1305 }
1306 if (!termios_locked[dev]) {
1307 termios_locked[dev] = ltp;
1308 ltp = NULL;
1309 }
1310 if (IS_A_PTY(dev)) {
1311 if (!tty_termios[o_dev]) {
1312 tty_termios[o_dev] = o_tp;
1313 o_tp = NULL;
1314 }
1315 if (!termios_locked[o_dev]) {
1316 termios_locked[o_dev] = o_ltp;
1317 o_ltp = NULL;
1318 }
1319 if (!tty_table[o_dev]) {
1320 o_tty->termios = tty_termios[o_dev];
1321 tty_table[o_dev] = o_tty;
1322 o_tty = NULL;
1323 }
1324 tty_table[dev]->link = tty_table[o_dev];
1325 tty_table[o_dev]->link = tty_table[dev];
1326 }
1327 tty_table[dev]->count++;
1328 if (IS_A_PTY_MASTER(dev))
1329 tty_table[o_dev]->count++;
1330 retval = 0;
1331 end_init:
1332 if (tty)
1333 free_page((unsigned long) tty);
1334 if (o_tty)
1335 free_page((unsigned long) o_tty);
1336 if (tp)
1337 kfree_s(tp, sizeof(struct termios));
1338 if (o_tp)
1339 kfree_s(o_tp, sizeof(struct termios));
1340 if (ltp)
1341 kfree_s(ltp, sizeof(struct termios));
1342 if (o_ltp)
1343 kfree_s(o_ltp, sizeof(struct termios));
1344 return retval;
1345 }
1346
1347
1348
1349
1350
1351
1352 static void release_dev(int dev, struct file * filp)
1353 {
1354 struct tty_struct *tty, *o_tty;
1355 struct termios *tp, *o_tp;
1356 struct task_struct **p;
1357
1358 tty = tty_table[dev];
1359 tp = tty_termios[dev];
1360 o_tty = NULL;
1361 o_tp = NULL;
1362 if (!tty) {
1363 printk("release_dev: tty_table[%d] was NULL\n", dev);
1364 return;
1365 }
1366 if (!tp) {
1367 printk("release_dev: tty_termios[%d] was NULL\n", dev);
1368 return;
1369 }
1370 #ifdef TTY_DEBUG_HANGUP
1371 printk("release_dev of tty%d (tty count=%d)...", dev, tty->count);
1372 #endif
1373 if (IS_A_PTY(dev)) {
1374 o_tty = tty_table[PTY_OTHER(dev)];
1375 o_tp = tty_termios[PTY_OTHER(dev)];
1376 if (!o_tty) {
1377 printk("release_dev: pty pair(%d) was NULL\n", dev);
1378 return;
1379 }
1380 if (!o_tp) {
1381 printk("release_dev: pty pair(%d) termios was NULL\n", dev);
1382 return;
1383 }
1384 if (tty->link != o_tty || o_tty->link != tty) {
1385 printk("release_dev: bad pty pointers\n");
1386 return;
1387 }
1388 }
1389 tty->write_data_cnt = 0;
1390 if (tty->close)
1391 tty->close(tty, filp);
1392 if (IS_A_PTY_MASTER(dev)) {
1393 if (--tty->link->count < 0) {
1394 printk("release_dev: bad tty slave count (dev = %d): %d\n",
1395 dev, tty->count);
1396 tty->link->count = 0;
1397 }
1398 }
1399 if (--tty->count < 0) {
1400 printk("release_dev: bad tty_table[%d]->count: %d\n",
1401 dev, tty->count);
1402 tty->count = 0;
1403 }
1404 if (tty->count)
1405 return;
1406
1407 #ifdef TTY_DEBUG_HANGUP
1408 printk("freeing tty structure...");
1409 #endif
1410
1411
1412
1413
1414
1415 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1416 if ((*p) && (*p)->tty == tty->line)
1417 (*p)->tty = -1;
1418 }
1419
1420
1421
1422
1423
1424 if (ldiscs[tty->disc].close != NULL)
1425 ldiscs[tty->disc].close(tty);
1426 tty->disc = N_TTY;
1427 tty->termios->c_line = N_TTY;
1428
1429 if (o_tty) {
1430 if (o_tty->count)
1431 return;
1432 else {
1433 tty_table[PTY_OTHER(dev)] = NULL;
1434 tty_termios[PTY_OTHER(dev)] = NULL;
1435 }
1436 }
1437 tty_table[dev] = NULL;
1438 if (IS_A_PTY(dev)) {
1439 tty_termios[dev] = NULL;
1440 kfree_s(tp, sizeof(struct termios));
1441 }
1442 if (tty == redirect || o_tty == redirect)
1443 redirect = NULL;
1444 free_page((unsigned long) tty);
1445 if (o_tty)
1446 free_page((unsigned long) o_tty);
1447 if (o_tp)
1448 kfree_s(o_tp, sizeof(struct termios));
1449 }
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463 static int tty_open(struct inode * inode, struct file * filp)
1464 {
1465 struct tty_struct *tty;
1466 int major, minor;
1467 int noctty, retval;
1468
1469 retry_open:
1470 minor = MINOR(inode->i_rdev);
1471 major = MAJOR(inode->i_rdev);
1472 noctty = filp->f_flags & O_NOCTTY;
1473 if (major == TTYAUX_MAJOR) {
1474 if (!minor) {
1475 major = TTY_MAJOR;
1476 minor = current->tty;
1477 }
1478
1479 } else if (major == TTY_MAJOR) {
1480 if (!minor) {
1481 minor = fg_console + 1;
1482 noctty = 1;
1483 }
1484 } else {
1485 printk("Bad major #%d in tty_open\n", MAJOR(inode->i_rdev));
1486 return -ENODEV;
1487 }
1488 if (minor <= 0)
1489 return -ENXIO;
1490 if (IS_A_PTY_MASTER(minor))
1491 noctty = 1;
1492 filp->f_rdev = (major << 8) | minor;
1493 retval = init_dev(minor);
1494 if (retval)
1495 return retval;
1496 tty = tty_table[minor];
1497 #ifdef TTY_DEBUG_HANGUP
1498 printk("opening tty%d...", tty->line);
1499 #endif
1500 if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
1501 return -EBUSY;
1502
1503 #if 0
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516 tty->ctrl_status = 0;
1517 tty->packet = 0;
1518 #endif
1519
1520 if (tty->open) {
1521 retval = tty->open(tty, filp);
1522 } else {
1523 retval = -ENODEV;
1524 }
1525 if (retval) {
1526 #ifdef TTY_DEBUG_HANGUP
1527 printk("error %d in opening tty%d...", retval, tty->line);
1528 #endif
1529
1530 release_dev(minor, filp);
1531 if (retval != -ERESTARTSYS)
1532 return retval;
1533 if (current->signal & ~current->blocked)
1534 return retval;
1535 schedule();
1536 goto retry_open;
1537 }
1538 if (!noctty &&
1539 current->leader &&
1540 current->tty<0 &&
1541 tty->session==0) {
1542 current->tty = minor;
1543 tty->session = current->session;
1544 tty->pgrp = current->pgrp;
1545 }
1546 filp->f_rdev = MKDEV(TTY_MAJOR,minor);
1547 return 0;
1548 }
1549
1550
1551
1552
1553
1554
1555 static void tty_release(struct inode * inode, struct file * filp)
1556 {
1557 int dev;
1558
1559 dev = filp->f_rdev;
1560 if (MAJOR(dev) != TTY_MAJOR) {
1561 printk("tty_release: tty pseudo-major != TTY_MAJOR\n");
1562 return;
1563 }
1564 dev = MINOR(filp->f_rdev);
1565 if (!dev) {
1566 printk("tty_release: bad f_rdev\n");
1567 return;
1568 }
1569 release_dev(dev, filp);
1570 }
1571
1572 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
1573 {
1574 int dev;
1575 struct tty_struct * tty;
1576
1577 dev = filp->f_rdev;
1578 if (MAJOR(dev) != TTY_MAJOR) {
1579 printk("tty_select: tty pseudo-major != TTY_MAJOR\n");
1580 return 0;
1581 }
1582 dev = MINOR(filp->f_rdev);
1583 tty = TTY_TABLE(dev);
1584 if (!tty) {
1585 printk("tty_select: tty struct for dev %d was NULL\n", dev);
1586 return 0;
1587 }
1588 if (ldiscs[tty->disc].select)
1589 return (ldiscs[tty->disc].select)(tty, inode, filp,
1590 sel_type, wait);
1591 return 0;
1592 }
1593
1594 static int normal_select(struct tty_struct * tty, struct inode * inode,
1595 struct file * file, int sel_type, select_table *wait)
1596 {
1597 switch (sel_type) {
1598 case SEL_IN:
1599 if (input_available_p(tty))
1600 return 1;
1601
1602 case SEL_EX:
1603 if (tty->packet && tty->link->ctrl_status)
1604 return 1;
1605 if (tty->flags & (1 << TTY_SLAVE_CLOSED))
1606 return 1;
1607 if (tty_hung_up_p(file))
1608 return 1;
1609 select_wait(&tty->secondary.proc_list, wait);
1610 return 0;
1611 case SEL_OUT:
1612 if (LEFT(&tty->write_q) > WAKEUP_CHARS)
1613 return 1;
1614 select_wait(&tty->write_q.proc_list, wait);
1615 return 0;
1616 }
1617 return 0;
1618 }
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632 void do_SAK( struct tty_struct *tty)
1633 {
1634 #ifdef TTY_SOFT_SAK
1635 tty_hangup(tty);
1636 #else
1637 struct task_struct **p;
1638 int line = tty->line;
1639 int session = tty->session;
1640 int i;
1641 struct file *filp;
1642
1643 flush_input(tty);
1644 flush_output(tty);
1645 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1646 if (!(*p))
1647 continue;
1648 if (((*p)->tty == line) ||
1649 ((session > 0) && ((*p)->session == session)))
1650 send_sig(SIGKILL, *p, 1);
1651 else {
1652 for (i=0; i < NR_OPEN; i++) {
1653 filp = (*p)->filp[i];
1654 if (filp && (filp->f_op == &tty_fops) &&
1655 (MINOR(filp->f_rdev) == line)) {
1656 send_sig(SIGKILL, *p, 1);
1657 break;
1658 }
1659 }
1660 }
1661 }
1662 #endif
1663 }
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680 int tty_write_data(struct tty_struct *tty, char *bufp, int buflen,
1681 void (*callback)(void * data), void * callarg)
1682 {
1683 int head, tail, count;
1684 unsigned long flags;
1685 char *p;
1686
1687 #define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
1688
1689 save_flags(flags);
1690 cli();
1691 if (tty->write_data_cnt) {
1692 restore_flags(flags);
1693 return -EBUSY;
1694 }
1695
1696 head = tty->write_q.head;
1697 tail = tty->write_q.tail;
1698 count = buflen;
1699 p = bufp;
1700
1701 while (count && VLEFT > 0) {
1702 tty->write_q.buf[head++] = *p++;
1703 head &= TTY_BUF_SIZE-1;
1704 count--;
1705 }
1706 tty->write_q.head = head;
1707 if (count) {
1708 tty->write_data_cnt = count;
1709 tty->write_data_ptr = (unsigned char *) p;
1710 tty->write_data_callback = callback;
1711 tty->write_data_arg = callarg;
1712 }
1713 restore_flags(flags);
1714 tty->write(tty);
1715 return count;
1716 }
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726 void tty_bh_routine(void * unused)
1727 {
1728 int i, j, line, mask;
1729 int head, tail, count;
1730 unsigned char * p;
1731 struct tty_struct * tty;
1732
1733 for (i = 0, line = 0; i < MAX_TTYS / 32; i++) {
1734 if (!tty_check_write[i]) {
1735 line += 32;
1736 continue;
1737 }
1738 for (j=0, mask=0; j < 32; j++, line++, mask <<= 1) {
1739 if (clear_bit(j, &tty_check_write[i])) {
1740 tty = tty_table[line];
1741 if (!tty || !tty->write_data_cnt)
1742 continue;
1743 cli();
1744 head = tty->write_q.head;
1745 tail = tty->write_q.tail;
1746 count = tty->write_data_cnt;
1747 p = tty->write_data_ptr;
1748
1749 while (count && VLEFT > 0) {
1750 tty->write_q.buf[head++] = *p++;
1751 head &= TTY_BUF_SIZE-1;
1752 count--;
1753 }
1754 tty->write_q.head = head;
1755 tty->write_data_ptr = p;
1756 tty->write_data_cnt = count;
1757 sti();
1758 if (!count)
1759 (tty->write_data_callback)
1760 (tty->write_data_arg);
1761 }
1762 }
1763 }
1764
1765 }
1766
1767
1768
1769
1770
1771 static void initialize_tty_struct(int line, struct tty_struct *tty)
1772 {
1773 memset(tty, 0, sizeof(struct tty_struct));
1774 tty->line = line;
1775 tty->disc = N_TTY;
1776 tty->pgrp = -1;
1777 if (IS_A_CONSOLE(line)) {
1778 tty->open = con_open;
1779 tty->winsize.ws_row = video_num_lines;
1780 tty->winsize.ws_col = video_num_columns;
1781 } else if IS_A_SERIAL(line) {
1782 tty->open = rs_open;
1783 } else if IS_A_PTY(line) {
1784 tty->open = pty_open;
1785 }
1786 }
1787
1788 static void initialize_termios(int line, struct termios * tp)
1789 {
1790 memset(tp, 0, sizeof(struct termios));
1791 memcpy(tp->c_cc, INIT_C_CC, NCCS);
1792 if (IS_A_CONSOLE(line) || IS_A_PTY_SLAVE(line)) {
1793 tp->c_iflag = ICRNL | IXON;
1794 tp->c_oflag = OPOST | ONLCR;
1795 tp->c_cflag = B38400 | CS8 | CREAD;
1796 tp->c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
1797 ECHOCTL | ECHOKE | IEXTEN;
1798 } else if (IS_A_SERIAL(line)) {
1799 tp->c_iflag = ICRNL | IXON;
1800 tp->c_oflag = OPOST | ONLCR | XTABS;
1801 tp->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1802 tp->c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
1803 ECHOCTL | ECHOKE | IEXTEN;
1804 } else if (IS_A_PTY_MASTER(line))
1805 tp->c_cflag = B9600 | CS8 | CREAD;
1806 }
1807
1808 static struct tty_ldisc tty_ldisc_N_TTY = {
1809 0,
1810 NULL,
1811 NULL,
1812 read_chan,
1813 write_chan,
1814 NULL,
1815 normal_select,
1816 copy_to_cooked
1817 };
1818
1819
1820 long tty_init(long kmem_start)
1821 {
1822 int i;
1823
1824 if (sizeof(struct tty_struct) > PAGE_SIZE)
1825 panic("size of tty structure > PAGE_SIZE!");
1826 if (register_chrdev(TTY_MAJOR,"tty",&tty_fops))
1827 panic("unable to get major %d for tty device", TTY_MAJOR);
1828 if (register_chrdev(TTYAUX_MAJOR,"tty",&tty_fops))
1829 panic("unable to get major %d for tty device", TTYAUX_MAJOR);
1830 for (i=0 ; i< MAX_TTYS ; i++) {
1831 tty_table[i] = 0;
1832 tty_termios[i] = 0;
1833 }
1834 memset(tty_check_write, 0, sizeof(tty_check_write));
1835 bh_base[TTY_BH].routine = tty_bh_routine;
1836
1837
1838 memset(ldiscs, 0, sizeof(ldiscs));
1839 (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1840
1841 kmem_start = kbd_init(kmem_start);
1842 kmem_start = con_init(kmem_start);
1843 kmem_start = rs_init(kmem_start);
1844 return kmem_start;
1845 }