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