This source file includes following definitions.
- pty_close
- pty_write
- pty_write_room
- pty_chars_in_buffer
- pty_flush_buffer
- pty_open
- pty_init
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/interrupt.h>
18 #include <linux/tty.h>
19 #include <linux/tty_flip.h>
20 #include <linux/fcntl.h>
21 #include <linux/string.h>
22 #include <linux/major.h>
23
24 #include <asm/segment.h>
25 #include <asm/system.h>
26 #include <asm/bitops.h>
27
28 struct pty_struct {
29 int magic;
30 struct wait_queue * open_wait;
31 };
32
33 #define PTY_MAGIC 0x5001
34
35 #define PTY_BUF_SIZE 1024
36
37 static unsigned char tmp_buf[PTY_BUF_SIZE];
38
39 struct tty_driver pty_driver, pty_slave_driver;
40 static int pty_refcount;
41
42 static struct tty_struct *pty_table[NR_PTYS];
43 static struct termios *pty_termios[NR_PTYS];
44 static struct termios *pty_termios_locked[NR_PTYS];
45 static struct tty_struct *ttyp_table[NR_PTYS];
46 static struct termios *ttyp_termios[NR_PTYS];
47 static struct termios *ttyp_termios_locked[NR_PTYS];
48 static struct pty_struct pty_state[NR_PTYS];
49
50 #define MIN(a,b) ((a) < (b) ? (a) : (b))
51
52 static void pty_close(struct tty_struct * tty, struct file * filp)
53 {
54 if (!tty)
55 return;
56 if (tty->driver.subtype == PTY_TYPE_MASTER) {
57 if (tty->count > 1)
58 printk("master pty_close: count = %d!!\n", tty->count);
59 } else {
60 if (tty->count > 2)
61 return;
62 }
63 wake_up_interruptible(&tty->read_wait);
64 wake_up_interruptible(&tty->write_wait);
65 if (!tty->link)
66 return;
67 wake_up_interruptible(&tty->link->read_wait);
68 wake_up_interruptible(&tty->link->write_wait);
69 if (tty->driver.subtype == PTY_TYPE_MASTER)
70 tty_hangup(tty->link);
71 else {
72 start_tty(tty);
73 set_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
74 }
75 }
76
77 static int pty_write(struct tty_struct * tty, int from_user,
78 unsigned char *buf, int count)
79 {
80 struct tty_struct *to = tty->link;
81 int c, n;
82
83 if (!to || tty->stopped)
84 return 0;
85
86 count = MIN(count, to->ldisc.receive_room(to));
87
88 if (from_user) {
89 for (c = count; c > 0; c -= n) {
90 n = MIN(c, PTY_BUF_SIZE);
91 memcpy_fromfs(tmp_buf, buf, n);
92 to->ldisc.receive_buf(to, tmp_buf, 0, n);
93 buf += n;
94 }
95 } else
96 to->ldisc.receive_buf(to, buf, 0, count);
97
98 return count;
99 }
100
101 static int pty_write_room(struct tty_struct *tty)
102 {
103 struct tty_struct *to = tty->link;
104
105 if (!to || tty->stopped)
106 return 0;
107
108 return to->ldisc.receive_room(to);
109 }
110
111 static int pty_chars_in_buffer(struct tty_struct *tty)
112 {
113 struct tty_struct *to = tty->link;
114
115 if (!to)
116 return 0;
117
118 return to->ldisc.chars_in_buffer(to);
119 }
120
121 static void pty_flush_buffer(struct tty_struct *tty)
122 {
123 struct tty_struct *to = tty->link;
124
125 if (!to)
126 return;
127
128 if (to->ldisc.flush_buffer)
129 to->ldisc.flush_buffer(to);
130
131 if (to->packet) {
132 tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
133 wake_up_interruptible(&to->read_wait);
134 }
135 }
136
137 int pty_open(struct tty_struct *tty, struct file * filp)
138 {
139 int line;
140 struct pty_struct *pty;
141
142 if (!tty || !tty->link)
143 return -ENODEV;
144 line = MINOR(tty->device) - tty->driver.minor_start;
145 if ((line < 0) || (line >= NR_PTYS))
146 return -ENODEV;
147 pty = pty_state + line;
148 tty->driver_data = pty;
149
150 if (tty->driver.subtype == PTY_TYPE_SLAVE)
151 clear_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
152 wake_up_interruptible(&pty->open_wait);
153 if (filp->f_flags & O_NDELAY)
154 return 0;
155 while (!tty->link->count && !(current->signal & ~current->blocked))
156 interruptible_sleep_on(&pty->open_wait);
157 if (!tty->link->count)
158 return -ERESTARTSYS;
159 return 0;
160 }
161
162 long pty_init(long kmem_start)
163 {
164 memset(&pty_state, 0, sizeof(pty_state));
165 memset(&pty_driver, 0, sizeof(struct tty_driver));
166 pty_driver.magic = TTY_DRIVER_MAGIC;
167 pty_driver.name = "pty";
168 pty_driver.major = TTY_MAJOR;
169 pty_driver.minor_start = 128;
170 pty_driver.num = NR_PTYS;
171 pty_driver.type = TTY_DRIVER_TYPE_PTY;
172 pty_driver.subtype = PTY_TYPE_MASTER;
173 pty_driver.init_termios = tty_std_termios;
174 pty_driver.init_termios.c_iflag = 0;
175 pty_driver.init_termios.c_oflag = 0;
176 pty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD;
177 pty_driver.init_termios.c_lflag = 0;
178 pty_driver.flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
179 pty_driver.refcount = &pty_refcount;
180 pty_driver.table = pty_table;
181 pty_driver.termios = pty_termios;
182 pty_driver.termios_locked = pty_termios_locked;
183 pty_driver.other = &pty_slave_driver;
184
185 pty_driver.open = pty_open;
186 pty_driver.close = pty_close;
187 pty_driver.write = pty_write;
188 pty_driver.write_room = pty_write_room;
189 pty_driver.flush_buffer = pty_flush_buffer;
190 pty_driver.chars_in_buffer = pty_chars_in_buffer;
191
192 pty_slave_driver = pty_driver;
193 pty_slave_driver.name = "ttyp";
194 pty_slave_driver.subtype = PTY_TYPE_SLAVE;
195 pty_slave_driver.minor_start = 192;
196 pty_slave_driver.init_termios = tty_std_termios;
197 pty_slave_driver.table = ttyp_table;
198 pty_slave_driver.termios = ttyp_termios;
199 pty_slave_driver.termios_locked = ttyp_termios_locked;
200 pty_slave_driver.other = &pty_driver;
201
202 if (tty_register_driver(&pty_driver))
203 panic("Couldn't register pty driver\n");
204 if (tty_register_driver(&pty_slave_driver))
205 panic("Couldn't register pty slave driver\n");
206
207 return kmem_start;
208 }
209
210