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