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