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