This source file includes following definitions.
- pty_close
- pty_copy
- pty_write
- pty_open
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <linux/errno.h>
16 #include <linux/sched.h>
17 #include <linux/tty.h>
18 #include <linux/fcntl.h>
19 #include <linux/interrupt.h>
20 #include <linux/string.h>
21
22 #include <asm/system.h>
23 #include <asm/bitops.h>
24
25 #define MIN(a,b) ((a) < (b) ? (a) : (b))
26
27 static void pty_close(struct tty_struct * tty, struct file * filp)
28 {
29 if (!tty)
30 return;
31 if (IS_A_PTY_MASTER(tty->line)) {
32 if (tty->count > 1)
33 printk("master pty_close: count = %d!!\n", tty->count);
34 } else {
35 if (tty->count > 2)
36 return;
37 }
38 wake_up_interruptible(&tty->secondary.proc_list);
39 wake_up_interruptible(&tty->read_q.proc_list);
40 wake_up_interruptible(&tty->write_q.proc_list);
41 if (!tty->link)
42 return;
43 wake_up_interruptible(&tty->link->secondary.proc_list);
44 wake_up_interruptible(&tty->link->read_q.proc_list);
45 wake_up_interruptible(&tty->link->write_q.proc_list);
46 if (IS_A_PTY_MASTER(tty->line))
47 tty_hangup(tty->link);
48 else {
49 start_tty(tty);
50 set_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
51 }
52 }
53
54 static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
55 {
56 unsigned long count, n;
57 struct tty_queue *fq, *tq;
58
59 if (from->stopped || EMPTY(&from->write_q))
60 return;
61 fq = &from->write_q;
62
63 tq = IS_A_PTY_MASTER(to->line) ? &to->secondary : &to->read_q;
64 count = MIN(CHARS(fq), LEFT(tq));
65 while (count) {
66 n = MIN(MIN(TTY_BUF_SIZE - fq->tail, TTY_BUF_SIZE - tq->head),
67 count);
68 memcpy(&tq->buf[tq->head], &fq->buf[fq->tail], n);
69 count -= n;
70 fq->tail = (fq->tail + n) & (TTY_BUF_SIZE - 1);
71 tq->head = (tq->head + n) & (TTY_BUF_SIZE - 1);
72 }
73 if (IS_A_PTY_MASTER(to->line))
74 wake_up_interruptible(&tq->proc_list);
75 else
76 TTY_READ_FLUSH(to);
77 if (LEFT(fq) > WAKEUP_CHARS)
78 wake_up_interruptible(&fq->proc_list);
79 if (from->write_data_cnt) {
80 set_bit(from->line, &tty_check_write);
81 mark_bh(TTY_BH);
82 }
83 }
84
85
86
87
88
89
90 static void pty_write(struct tty_struct * tty)
91 {
92 if (tty->link)
93 pty_copy(tty,tty->link);
94 }
95
96 int pty_open(struct tty_struct *tty, struct file * filp)
97 {
98 if (!tty || !tty->link)
99 return -ENODEV;
100 if (IS_A_PTY_SLAVE(tty->line))
101 clear_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
102 tty->write = tty->link->write = pty_write;
103 tty->close = tty->link->close = pty_close;
104 wake_up_interruptible(&tty->read_q.proc_list);
105 if (filp->f_flags & O_NDELAY)
106 return 0;
107 while (!tty->link->count && !(current->signal & ~current->blocked))
108 interruptible_sleep_on(&tty->link->read_q.proc_list);
109 if (!tty->link->count)
110 return -ERESTARTSYS;
111 return 0;
112 }