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 long 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) || c == WERASE_CHAR(tty)) {
549 int seen_alnums =
550 (c == WERASE_CHAR(tty)) ? 0 : -1;
551
552
553 while(!(EMPTY(&tty->secondary) ||
554 (c=LAST(&tty->secondary))==10 ||
555 ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
556 (c==EOF_CHAR(tty))))) {
557
558
559
560 if (seen_alnums >= 0) {
561 if (isalnum(c))
562 seen_alnums++;
563 else if (seen_alnums)
564 break;
565 }
566 if (L_ECHO(tty)) {
567 if (c<32) {
568 put_tty_queue(8, &tty->write_q);
569 put_tty_queue(' ', &tty->write_q);
570 put_tty_queue(8,&tty->write_q);
571 }
572 put_tty_queue(8,&tty->write_q);
573 put_tty_queue(' ',&tty->write_q);
574 put_tty_queue(8,&tty->write_q);
575 }
576 DEC(tty->secondary.head);
577 }
578 continue;
579 }
580 if (c == ERASE_CHAR(tty)) {
581 if (EMPTY(&tty->secondary) ||
582 (c=LAST(&tty->secondary))==10 ||
583 ((EOF_CHAR(tty) != __DISABLED_CHAR) &&
584 (c==EOF_CHAR(tty))))
585 continue;
586 if (L_ECHO(tty)) {
587 if (c<32) {
588 put_tty_queue(8,&tty->write_q);
589 put_tty_queue(' ',&tty->write_q);
590 put_tty_queue(8,&tty->write_q);
591 }
592 put_tty_queue(8,&tty->write_q);
593 put_tty_queue(32,&tty->write_q);
594 put_tty_queue(8,&tty->write_q);
595 }
596 DEC(tty->secondary.head);
597 continue;
598 }
599 if (c == LNEXT_CHAR(tty)) {
600 tty->lnext = 1;
601 if (L_ECHO(tty)) {
602 put_tty_queue('^',&tty->write_q);
603 put_tty_queue(8,&tty->write_q);
604 }
605 continue;
606 }
607 }
608 if (I_IXON(tty) && !tty->lnext) {
609 if (c == STOP_CHAR(tty)) {
610 tty->status_changed = 1;
611 tty->ctrl_status |= TIOCPKT_STOP;
612 tty->stopped=1;
613 if (IS_A_CONSOLE(tty->line)) {
614 set_vc_kbd_flag(kbd_table + fg_console, VC_SCROLLOCK);
615 set_leds();
616 }
617 continue;
618 }
619 if (((I_IXANY(tty)) && tty->stopped) ||
620 (c == START_CHAR(tty))) {
621 tty->status_changed = 1;
622 tty->ctrl_status |= TIOCPKT_START;
623 tty->stopped=0;
624 if (IS_A_CONSOLE(tty->line)) {
625 clr_vc_kbd_flag(kbd_table + fg_console, VC_SCROLLOCK);
626 set_leds();
627 }
628 continue;
629 }
630 }
631 if (L_ISIG(tty) && !tty->lnext) {
632 if (c == INTR_CHAR(tty)) {
633 kill_pg(tty->pgrp, SIGINT, 1);
634 flush_input(tty);
635 continue;
636 }
637 if (c == QUIT_CHAR(tty)) {
638 kill_pg(tty->pgrp, SIGQUIT, 1);
639 flush_input(tty);
640 continue;
641 }
642 if (c == SUSPEND_CHAR(tty)) {
643 if (!is_orphaned_pgrp(tty->pgrp)) {
644 kill_pg(tty->pgrp, SIGTSTP, 1);
645 flush_input(tty);
646 }
647 continue;
648 }
649 }
650 if (c==10 || (EOF_CHAR(tty) != __DISABLED_CHAR &&
651 c==EOF_CHAR(tty)))
652 tty->secondary.data++;
653 if ((c==10) && (L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty)))) {
654 put_tty_queue(10,&tty->write_q);
655 put_tty_queue(13,&tty->write_q);
656 } else if (L_ECHO(tty)) {
657 if (c<32 && L_ECHOCTL(tty)) {
658 put_tty_queue('^',&tty->write_q);
659 put_tty_queue(c+64, &tty->write_q);
660 if (EOF_CHAR(tty) != __DISABLED_CHAR &&
661 c==EOF_CHAR(tty) && !tty->lnext) {
662 put_tty_queue(8,&tty->write_q);
663 put_tty_queue(8,&tty->write_q);
664 }
665 } else
666 put_tty_queue(c, &tty->write_q);
667 }
668 tty->lnext = 0;
669 put_tty_queue(c, &tty->secondary);
670 }
671 TTY_WRITE_FLUSH(tty);
672 if (!EMPTY(&tty->secondary))
673 wake_up_interruptible(&tty->secondary.proc_list);
674 if (tty->write_q.proc_list && LEFT(&tty->write_q) > TTY_BUF_SIZE/2)
675 wake_up_interruptible(&tty->write_q.proc_list);
676 if (tty->throttle && (LEFT(&tty->read_q) >= RQ_THRESHOLD_HW)
677 && !clear_bit(TTY_RQ_THROTTLED, &tty->flags))
678 tty->throttle(tty, TTY_THROTTLE_RQ_AVAIL);
679 if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
680 && !clear_bit(TTY_SQ_THROTTLED, &tty->flags))
681 tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
682 }
683
684 int is_ignored(int sig)
685 {
686 return ((current->blocked & (1<<(sig-1))) ||
687 (current->sigaction[sig-1].sa_handler == SIG_IGN));
688 }
689
690 static int available_canon_input(struct tty_struct *);
691 static void __wait_for_canon_input(struct file * file, struct tty_struct *);
692
693 static void wait_for_canon_input(struct file * file, struct tty_struct * tty)
694 {
695 if (!available_canon_input(tty)) {
696 if (current->signal & ~current->blocked)
697 return;
698 __wait_for_canon_input(file, tty);
699 }
700 }
701
702 static int read_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
703 {
704 struct wait_queue wait = { current, NULL };
705 int c;
706 char * b=buf;
707 int minimum,time;
708
709 if (L_CANON(tty))
710 minimum = time = current->timeout = 0;
711 else {
712 time = 10L*tty->termios->c_cc[VTIME];
713 minimum = tty->termios->c_cc[VMIN];
714 if (minimum)
715 current->timeout = 0xffffffff;
716 else {
717 if (time)
718 current->timeout = time + jiffies;
719 else
720 current->timeout = 0;
721 time = 0;
722 minimum = 1;
723 }
724 }
725 if (file->f_flags & O_NONBLOCK) {
726 time = current->timeout = 0;
727 if (L_CANON(tty)) {
728 if (!available_canon_input(tty))
729 return -EAGAIN;
730 }
731 } else if (L_CANON(tty)) {
732 wait_for_canon_input(file, tty);
733 if (current->signal & ~current->blocked)
734 return -ERESTARTSYS;
735 }
736 if (minimum>nr)
737 minimum = nr;
738
739
740 if (tty->packet && tty->link && tty->link->status_changed) {
741 put_fs_byte (tty->link->ctrl_status, b);
742 tty->link->status_changed = 0;
743 return 1;
744 }
745
746
747 if (tty->packet) {
748 put_fs_byte (0,b++);
749 nr--;
750
751
752 if (nr == 0)
753 return 1;
754 }
755 add_wait_queue(&tty->secondary.proc_list, &wait);
756 while (nr>0) {
757 if (tty_hung_up_p(file)) {
758 file->f_flags &= ~O_NONBLOCK;
759 break;
760 }
761 TTY_READ_FLUSH(tty);
762 if (tty->link)
763 TTY_WRITE_FLUSH(tty->link);
764 while (nr > 0 && ((c = get_tty_queue(&tty->secondary)) >= 0)) {
765 if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
766 c==EOF_CHAR(tty)) || c==10)
767 tty->secondary.data--;
768 if ((EOF_CHAR(tty) != __DISABLED_CHAR &&
769 c==EOF_CHAR(tty)) && L_CANON(tty))
770 break;
771 put_fs_byte(c,b++);
772 nr--;
773 if (time)
774 current->timeout = time+jiffies;
775 if (c==10 && L_CANON(tty))
776 break;
777 };
778 wake_up_interruptible(&tty->read_q.proc_list);
779
780
781
782
783 if (tty->throttle && (LEFT(&tty->secondary) >= SQ_THRESHOLD_HW)
784 && !clear_bit(TTY_SQ_THROTTLED, &tty->flags))
785 tty->throttle(tty, TTY_THROTTLE_SQ_AVAIL);
786 if (b-buf >= minimum || !current->timeout)
787 break;
788 if (current->signal & ~current->blocked)
789 break;
790 if (tty->link && !tty->link->count)
791 break;
792 TTY_READ_FLUSH(tty);
793 if (tty->link)
794 TTY_WRITE_FLUSH(tty->link);
795 if (!EMPTY(&tty->secondary))
796 continue;
797 current->state = TASK_INTERRUPTIBLE;
798 if (EMPTY(&tty->secondary))
799 schedule();
800 current->state = TASK_RUNNING;
801 }
802 remove_wait_queue(&tty->secondary.proc_list, &wait);
803 TTY_READ_FLUSH(tty);
804 if (tty->link && tty->link->write)
805 TTY_WRITE_FLUSH(tty->link);
806 current->timeout = 0;
807
808
809
810 if (tty->packet) {
811 if ((b-buf) > 1)
812 return b-buf;
813 } else {
814 if (b-buf)
815 return b-buf;
816 }
817
818 if (current->signal & ~current->blocked)
819 return -ERESTARTSYS;
820 if (file->f_flags & O_NONBLOCK)
821 return -EAGAIN;
822 return 0;
823 }
824
825 static void __wait_for_canon_input(struct file * file, struct tty_struct * tty)
826 {
827 struct wait_queue wait = { current, NULL };
828
829 add_wait_queue(&tty->secondary.proc_list, &wait);
830 while (1) {
831 current->state = TASK_INTERRUPTIBLE;
832 if (available_canon_input(tty))
833 break;
834 if (current->signal & ~current->blocked)
835 break;
836 if (tty_hung_up_p(file))
837 break;
838 schedule();
839 }
840 current->state = TASK_RUNNING;
841 remove_wait_queue(&tty->secondary.proc_list, &wait);
842 }
843
844 static int available_canon_input(struct tty_struct * tty)
845 {
846 TTY_READ_FLUSH(tty);
847 if (tty->link)
848 if (tty->link->count)
849 TTY_WRITE_FLUSH(tty->link);
850 else
851 return 1;
852 if (FULL(&tty->read_q))
853 return 1;
854 if (tty->secondary.data)
855 return 1;
856 return 0;
857 }
858
859 static int write_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
860 {
861 struct wait_queue wait = { current, NULL };
862 char c, *b=buf;
863
864 if (nr < 0)
865 return -EINVAL;
866 if (!nr)
867 return 0;
868 add_wait_queue(&tty->write_q.proc_list, &wait);
869 while (nr>0) {
870 if (current->signal & ~current->blocked)
871 break;
872 if (tty_hung_up_p(file))
873 break;
874 if (tty->link && !tty->link->count) {
875 send_sig(SIGPIPE,current,0);
876 break;
877 }
878 current->state = TASK_INTERRUPTIBLE;
879 if (FULL(&tty->write_q)) {
880 TTY_WRITE_FLUSH(tty);
881 if (FULL(&tty->write_q))
882 schedule();
883 current->state = TASK_RUNNING;
884 continue;
885 }
886 current->state = TASK_RUNNING;
887 while (nr>0 && !FULL(&tty->write_q)) {
888 c=get_fs_byte(b);
889 if (O_POST(tty)) {
890 if (c=='\r' && O_CRNL(tty))
891 c='\n';
892 else if (c=='\n' && O_NLRET(tty))
893 c='\r';
894 if (c=='\n' && O_NLCR(tty) &&
895 !set_bit(TTY_CR_PENDING,&tty->flags)) {
896 put_tty_queue(13,&tty->write_q);
897 continue;
898 }
899 if (O_LCUC(tty))
900 c=toupper(c);
901 }
902 b++; nr--;
903 clear_bit(TTY_CR_PENDING,&tty->flags);
904 put_tty_queue(c,&tty->write_q);
905 }
906 if (need_resched)
907 schedule();
908 }
909 remove_wait_queue(&tty->write_q.proc_list, &wait);
910 TTY_WRITE_FLUSH(tty);
911 if (b-buf)
912 return b-buf;
913 if (tty->link && !tty->link->count)
914 return -EPIPE;
915 if (current->signal & ~current->blocked)
916 return -ERESTARTSYS;
917 return 0;
918 }
919
920 static int tty_read(struct inode * inode, struct file * file, char * buf, int count)
921 {
922 int i, dev;
923 struct tty_struct * tty;
924
925 dev = file->f_rdev;
926 if (MAJOR(dev) != 4) {
927 printk("tty_read: bad pseudo-major nr #%d\n", MAJOR(dev));
928 return -EINVAL;
929 }
930 dev = MINOR(dev);
931 tty = TTY_TABLE(dev);
932 if (!tty || (tty->flags & (1 << TTY_IO_ERROR)))
933 return -EIO;
934 if ((inode->i_rdev != 0x0400) &&
935 (tty->pgrp > 0) &&
936 (current->tty == dev) &&
937 (tty->pgrp != current->pgrp))
938 if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
939 return -EIO;
940 else {
941 (void) kill_pg(current->pgrp, SIGTTIN, 1);
942 return -ERESTARTSYS;
943 }
944 if (ldiscs[tty->disc].read)
945 i = (ldiscs[tty->disc].read)(tty,file,buf,count);
946 else
947 i = -EIO;
948 if (i > 0)
949 inode->i_atime = CURRENT_TIME;
950 return i;
951 }
952
953 static int tty_write(struct inode * inode, struct file * file, char * buf, int count)
954 {
955 int dev, i, is_console;
956 struct tty_struct * tty;
957
958 dev = file->f_rdev;
959 is_console = (inode->i_rdev == 0x0400);
960 if (MAJOR(dev) != 4) {
961 printk("tty_write: pseudo-major != 4\n");
962 return -EINVAL;
963 }
964 dev = MINOR(dev);
965 if (is_console && redirect)
966 tty = redirect;
967 else
968 tty = TTY_TABLE(dev);
969 if (!tty || !tty->write || (tty->flags & (1 << TTY_IO_ERROR)))
970 return -EIO;
971 if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
972 (current->tty == dev) && (tty->pgrp != current->pgrp)) {
973 if (is_orphaned_pgrp(current->pgrp))
974 return -EIO;
975 if (!is_ignored(SIGTTOU)) {
976 (void) kill_pg(current->pgrp, SIGTTOU, 1);
977 return -ERESTARTSYS;
978 }
979 }
980 if (ldiscs[tty->disc].write)
981 i = (ldiscs[tty->disc].write)(tty,file,buf,count);
982 else
983 i = -EIO;
984 if (i > 0)
985 inode->i_mtime = CURRENT_TIME;
986 return i;
987 }
988
989
990
991
992
993
994 static int init_dev(int dev)
995 {
996 struct tty_struct *tty, *o_tty;
997 struct termios *tp, *o_tp;
998 int retval;
999 int o_dev;
1000
1001 o_dev = PTY_OTHER(dev);
1002 tty = o_tty = NULL;
1003 tp = o_tp = NULL;
1004 repeat:
1005 retval = -EAGAIN;
1006 if (IS_A_PTY_MASTER(dev) && tty_table[dev] && tty_table[dev]->count)
1007 goto end_init;
1008 retval = -ENOMEM;
1009 if (!tty_table[dev] && !tty) {
1010 tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
1011 if (!tty)
1012 goto end_init;
1013 initialize_tty_struct(dev, tty);
1014 goto repeat;
1015 }
1016 if (!tty_termios[dev] && !tp) {
1017 tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
1018 if (!tp)
1019 goto end_init;
1020 initialize_termios(dev, tp);
1021 goto repeat;
1022 }
1023 if (IS_A_PTY(dev)) {
1024 if (!tty_table[o_dev] && !o_tty) {
1025 o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
1026 if (!o_tty)
1027 goto end_init;
1028 initialize_tty_struct(o_dev, o_tty);
1029 goto repeat;
1030 }
1031 if (!tty_termios[o_dev] && !o_tp) {
1032 o_tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL);
1033 if (!o_tp)
1034 goto end_init;
1035 initialize_termios(o_dev, o_tp);
1036 goto repeat;
1037 }
1038 }
1039
1040 if (!tty_termios[dev]) {
1041 tty_termios[dev] = tp;
1042 tp = NULL;
1043 }
1044 if (!tty_table[dev]) {
1045 tty->termios = tty_termios[dev];
1046 tty_table[dev] = tty;
1047 tty = NULL;
1048 }
1049 if (IS_A_PTY(dev)) {
1050 if (!tty_termios[o_dev]) {
1051 tty_termios[o_dev] = o_tp;
1052 o_tp = NULL;
1053 }
1054 if (!tty_table[o_dev]) {
1055 o_tty->termios = tty_termios[o_dev];
1056 tty_table[o_dev] = o_tty;
1057 o_tty = NULL;
1058 }
1059 tty_table[dev]->link = tty_table[o_dev];
1060 tty_table[o_dev]->link = tty_table[dev];
1061 }
1062 tty_table[dev]->count++;
1063 if (IS_A_PTY_MASTER(dev))
1064 tty_table[o_dev]->count++;
1065 retval = 0;
1066 end_init:
1067 if (tty)
1068 free_page((unsigned long) tty);
1069 if (o_tty)
1070 free_page((unsigned long) o_tty);
1071 if (tp)
1072 kfree_s(tp, sizeof(struct termios));
1073 if (o_tp)
1074 kfree_s(o_tp, sizeof(struct termios));
1075 return retval;
1076 }
1077
1078
1079
1080
1081
1082
1083 static void release_dev(int dev, struct file * filp)
1084 {
1085 struct tty_struct *tty, *o_tty;
1086 struct termios *tp, *o_tp;
1087 struct task_struct **p;
1088
1089 tty = tty_table[dev];
1090 tp = tty_termios[dev];
1091 o_tty = NULL;
1092 o_tp = NULL;
1093 if (!tty) {
1094 printk("release_dev: tty_table[%d] was NULL\n", dev);
1095 return;
1096 }
1097 if (!tp) {
1098 printk("release_dev: tty_termios[%d] was NULL\n", dev);
1099 return;
1100 }
1101 if (IS_A_PTY(dev)) {
1102 o_tty = tty_table[PTY_OTHER(dev)];
1103 o_tp = tty_termios[PTY_OTHER(dev)];
1104 if (!o_tty) {
1105 printk("release_dev: pty pair(%d) was NULL\n", dev);
1106 return;
1107 }
1108 if (!o_tp) {
1109 printk("release_dev: pty pair(%d) termios was NULL\n", dev);
1110 return;
1111 }
1112 if (tty->link != o_tty || o_tty->link != tty) {
1113 printk("release_dev: bad pty pointers\n");
1114 return;
1115 }
1116 }
1117 tty->write_data_cnt = 0;
1118 if (tty->close)
1119 tty->close(tty, filp);
1120 if (IS_A_PTY_MASTER(dev)) {
1121 if (--tty->link->count < 0) {
1122 printk("release_dev: bad tty slave count (dev = %d): %d\n",
1123 dev, tty->count);
1124 tty->link->count = 0;
1125 }
1126 }
1127 if (--tty->count < 0) {
1128 printk("release_dev: bad tty_table[%d]->count: %d\n",
1129 dev, tty->count);
1130 tty->count = 0;
1131 }
1132 if (tty->count)
1133 return;
1134
1135
1136
1137
1138
1139 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1140 if ((*p) && (*p)->tty == tty->line)
1141 (*p)->tty = -1;
1142 }
1143
1144 if (ldiscs[tty->disc].close != NULL)
1145 ldiscs[tty->disc].close(tty);
1146
1147 if (o_tty) {
1148 if (o_tty->count)
1149 return;
1150 else {
1151 tty_table[PTY_OTHER(dev)] = NULL;
1152 tty_termios[PTY_OTHER(dev)] = NULL;
1153 }
1154 }
1155 tty_table[dev] = NULL;
1156 if (IS_A_PTY(dev)) {
1157 tty_termios[dev] = NULL;
1158 kfree_s(tp, sizeof(struct termios));
1159 }
1160 if (tty == redirect || o_tty == redirect)
1161 redirect = NULL;
1162 free_page((unsigned long) tty);
1163 if (o_tty)
1164 free_page((unsigned long) o_tty);
1165 if (o_tp)
1166 kfree_s(o_tp, sizeof(struct termios));
1167 }
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181 static int tty_open(struct inode * inode, struct file * filp)
1182 {
1183 struct tty_struct *tty;
1184 int major, minor;
1185 int noctty, retval;
1186
1187 minor = MINOR(inode->i_rdev);
1188 major = MAJOR(inode->i_rdev);
1189 noctty = filp->f_flags & O_NOCTTY;
1190 if (major == 5) {
1191 if (!minor) {
1192 major = 4;
1193 minor = current->tty;
1194 }
1195 noctty = 1;
1196 } else if (major == 4) {
1197 if (!minor) {
1198 minor = fg_console + 1;
1199 noctty = 1;
1200 }
1201 } else {
1202 printk("Bad major #%d in tty_open\n", MAJOR(inode->i_rdev));
1203 return -ENODEV;
1204 }
1205 if (minor <= 0)
1206 return -ENXIO;
1207 if (IS_A_PTY_MASTER(minor))
1208 noctty = 1;
1209 filp->f_rdev = (major << 8) | minor;
1210 retval = init_dev(minor);
1211 if (retval)
1212 return retval;
1213 tty = tty_table[minor];
1214
1215
1216
1217
1218
1219
1220
1221
1222 tty->status_changed = 0;
1223 tty->ctrl_status = 0;
1224 tty->packet = 0;
1225
1226 if (tty->open) {
1227 retval = tty->open(tty, filp);
1228 } else {
1229 retval = -ENODEV;
1230 }
1231 if (retval) {
1232 release_dev(minor, filp);
1233 return retval;
1234 }
1235 if (!noctty &&
1236 current->leader &&
1237 current->tty<0 &&
1238 tty->session==0) {
1239 current->tty = minor;
1240 tty->session = current->session;
1241 tty->pgrp = current->pgrp;
1242 }
1243 filp->f_rdev = 0x0400 | minor;
1244 return 0;
1245 }
1246
1247
1248
1249
1250
1251
1252 static void tty_release(struct inode * inode, struct file * filp)
1253 {
1254 int dev;
1255
1256 dev = filp->f_rdev;
1257 if (MAJOR(dev) != 4) {
1258 printk("tty_release: tty pseudo-major != 4\n");
1259 return;
1260 }
1261 dev = MINOR(filp->f_rdev);
1262 if (!dev) {
1263 printk("tty_release: bad f_rdev\n");
1264 return;
1265 }
1266 release_dev(dev, filp);
1267 }
1268
1269 static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
1270 {
1271 int dev;
1272 struct tty_struct * tty;
1273
1274 dev = filp->f_rdev;
1275 if (MAJOR(dev) != 4) {
1276 printk("tty_select: tty pseudo-major != 4\n");
1277 return 0;
1278 }
1279 dev = MINOR(filp->f_rdev);
1280 tty = TTY_TABLE(dev);
1281 if (!tty) {
1282 printk("tty_select: tty struct for dev %d was NULL\n", dev);
1283 return 0;
1284 }
1285 switch (sel_type) {
1286 case SEL_IN:
1287 if (L_CANON(tty)) {
1288 if (available_canon_input(tty))
1289 return 1;
1290 } else if (!EMPTY(&tty->secondary))
1291 return 1;
1292 if (tty->link && !tty->link->count)
1293 return 1;
1294
1295
1296 if (tty->packet && tty->link &&
1297 tty->link->status_changed)
1298 return 1;
1299
1300 select_wait(&tty->secondary.proc_list, wait);
1301 return 0;
1302 case SEL_OUT:
1303 if (!FULL(&tty->write_q))
1304 return 1;
1305 select_wait(&tty->write_q.proc_list, wait);
1306 return 0;
1307 case SEL_EX:
1308 if (tty->link && !tty->link->count)
1309 return 1;
1310 return 0;
1311 }
1312 return 0;
1313 }
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327 void do_SAK( struct tty_struct *tty)
1328 {
1329 struct task_struct **p;
1330 int line = tty->line;
1331 int session = tty->session;
1332 int i;
1333 struct file *filp;
1334
1335 flush_input(tty);
1336 flush_output(tty);
1337 for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
1338 if (!(*p))
1339 continue;
1340 if (((*p)->tty == line) ||
1341 ((session > 0) && ((*p)->session == session)))
1342 send_sig(SIGKILL, *p, 1);
1343 else {
1344 for (i=0; i < NR_FILE; i++) {
1345 filp = (*p)->filp[i];
1346 if (filp && (filp->f_op == &tty_fops) &&
1347 (MINOR(filp->f_rdev) == line)) {
1348 send_sig(SIGKILL, *p, 1);
1349 break;
1350 }
1351 }
1352 }
1353 }
1354 }
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371 int tty_write_data(struct tty_struct *tty, char *bufp, int buflen,
1372 void (*callback)(void * data), void * callarg)
1373 {
1374 int head, tail, count;
1375 unsigned long flags;
1376 char *p;
1377
1378 #define VLEFT ((tail-head-1)&(TTY_BUF_SIZE-1))
1379
1380 __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
1381 if (tty->write_data_cnt) {
1382 __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
1383 return -EBUSY;
1384 }
1385
1386 head = tty->write_q.head;
1387 tail = tty->write_q.tail;
1388 count = buflen;
1389 p = bufp;
1390
1391 while (count && VLEFT > 0) {
1392 tty->write_q.buf[head++] = *p++;
1393 head &= TTY_BUF_SIZE-1;
1394 }
1395 tty->write_q.head = head;
1396 if (count) {
1397 tty->write_data_cnt = count;
1398 tty->write_data_ptr = p;
1399 tty->write_data_callback = callback;
1400 tty->write_data_arg = callarg;
1401 }
1402 __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
1403 return count;
1404 }
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 void tty_bh_routine(void * unused)
1415 {
1416 int i, j, line, mask;
1417 int head, tail, count;
1418 unsigned char * p;
1419 struct tty_struct * tty;
1420
1421 for (i = 0, line = 0; i < MAX_TTYS / 32; i++) {
1422 if (!tty_check_write[i]) {
1423 line += 32;
1424 continue;
1425 }
1426 for (j=0, mask=0; j < 32; j++, line++, mask <<= 1) {
1427 if (!clear_bit(j, &tty_check_write[i])) {
1428 tty = tty_table[line];
1429 if (!tty || !tty->write_data_cnt)
1430 continue;
1431 cli();
1432 head = tty->write_q.head;
1433 tail = tty->write_q.tail;
1434 count = tty->write_data_cnt;
1435 p = tty->write_data_ptr;
1436
1437 while (count && VLEFT > 0) {
1438 tty->write_q.buf[head++] = *p++;
1439 head &= TTY_BUF_SIZE-1;
1440 }
1441 tty->write_q.head = head;
1442 tty->write_data_ptr = p;
1443 tty->write_data_cnt = count;
1444 sti();
1445 if (!count)
1446 (tty->write_data_callback)
1447 (tty->write_data_arg);
1448 }
1449 }
1450 }
1451
1452 }
1453
1454
1455
1456
1457
1458 static void initialize_tty_struct(int line, struct tty_struct *tty)
1459 {
1460 memset(tty, 0, sizeof(struct tty_struct));
1461 tty->line = line;
1462 tty->disc = N_TTY;
1463 tty->pgrp = -1;
1464 tty->winsize.ws_row = 0;
1465 tty->winsize.ws_col = 0;
1466 if (IS_A_CONSOLE(line)) {
1467 tty->open = con_open;
1468 tty->winsize.ws_row = video_num_lines;
1469 tty->winsize.ws_col = video_num_columns;
1470 } else if IS_A_SERIAL(line) {
1471 tty->open = rs_open;
1472 } else if IS_A_PTY(line) {
1473 tty->open = pty_open;
1474 }
1475 }
1476
1477 static void initialize_termios(int line, struct termios * tp)
1478 {
1479 memset(tp, 0, sizeof(struct termios));
1480 memcpy(tp->c_cc, INIT_C_CC, NCCS);
1481 if (IS_A_CONSOLE(line)) {
1482 tp->c_iflag = ICRNL | IXON;
1483 tp->c_oflag = OPOST | ONLCR;
1484 tp->c_cflag = B38400 | CS8 | CREAD;
1485 tp->c_lflag = ISIG | ICANON | ECHO |
1486 ECHOCTL | ECHOKE;
1487 } else if (IS_A_SERIAL(line)) {
1488 tp->c_cflag = B2400 | CS8 | CREAD | HUPCL | CLOCAL;
1489 } else if (IS_A_PTY_MASTER(line)) {
1490 tp->c_cflag = B9600 | CS8 | CREAD;
1491 } else if (IS_A_PTY_SLAVE(line)) {
1492 tp->c_iflag = ICRNL | IXON;
1493 tp->c_oflag = OPOST | ONLCR;
1494 tp->c_cflag = B38400 | CS8 | CREAD;
1495 tp->c_lflag = ISIG | ICANON | ECHO |
1496 ECHOCTL | ECHOKE;
1497 }
1498 }
1499
1500 static struct tty_ldisc tty_ldisc_N_TTY = {
1501 0,
1502 NULL,
1503 NULL,
1504 read_chan,
1505 write_chan,
1506 NULL,
1507 copy_to_cooked
1508 };
1509
1510
1511 long tty_init(long kmem_start)
1512 {
1513 int i;
1514
1515 if (sizeof(struct tty_struct) > 4096)
1516 panic("size of tty structure > 4096!");
1517 if (register_chrdev(4,"tty",&tty_fops))
1518 panic("unable to get major 4 for tty device");
1519 if (register_chrdev(5,"tty",&tty_fops))
1520 panic("unable to get major 5 for tty device");
1521 for (i=0 ; i< MAX_TTYS ; i++) {
1522 tty_table[i] = 0;
1523 tty_termios[i] = 0;
1524 }
1525 memset(tty_check_write, 0, sizeof(tty_check_write));
1526 bh_base[TTY_BH].routine = tty_bh_routine;
1527
1528
1529 memset(ldiscs, 0, sizeof(ldiscs));
1530 (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
1531
1532 kmem_start = kbd_init(kmem_start);
1533 kmem_start = con_init(kmem_start);
1534 kmem_start = rs_init(kmem_start);
1535 return kmem_start;
1536 }