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