2 * linux/drivers/char/tty_ioctl.c
4 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
6 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
7 * which can be dynamically activated and de-activated by the line
8 * discipline handling modules (like SLIP).
11 #include <linux/types.h>
12 #include <linux/termios.h>
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/major.h>
17 #include <linux/tty.h>
18 #include <linux/fcntl.h>
19 #include <linux/string.h>
21 #include <linux/module.h>
22 #include <linux/bitops.h>
23 #include <linux/mutex.h>
26 #include <asm/uaccess.h>
27 #include <asm/system.h>
29 #undef TTY_DEBUG_WAIT_UNTIL_SENT
34 * Internal flag options for termios setting behavior
36 #define TERMIOS_FLUSH 1
37 #define TERMIOS_WAIT 2
38 #define TERMIOS_TERMIO 4
42 * tty_wait_until_sent - wait for I/O to finish
43 * @tty: tty we are waiting for
44 * @timeout: how long we will wait
46 * Wait for characters pending in a tty driver to hit the wire, or
47 * for a timeout to occur (eg due to flow control)
52 void tty_wait_until_sent(struct tty_struct
* tty
, long timeout
)
54 DECLARE_WAITQUEUE(wait
, current
);
56 #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
59 printk(KERN_DEBUG
"%s wait until sent...\n", tty_name(tty
, buf
));
61 if (!tty
->driver
->chars_in_buffer
)
63 add_wait_queue(&tty
->write_wait
, &wait
);
65 timeout
= MAX_SCHEDULE_TIMEOUT
;
67 #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
68 printk(KERN_DEBUG
"waiting %s...(%d)\n", tty_name(tty
, buf
),
69 tty
->driver
->chars_in_buffer(tty
));
71 set_current_state(TASK_INTERRUPTIBLE
);
72 if (signal_pending(current
))
74 if (!tty
->driver
->chars_in_buffer(tty
))
76 timeout
= schedule_timeout(timeout
);
78 if (tty
->driver
->wait_until_sent
)
79 tty
->driver
->wait_until_sent(tty
, timeout
);
81 set_current_state(TASK_RUNNING
);
82 remove_wait_queue(&tty
->write_wait
, &wait
);
85 EXPORT_SYMBOL(tty_wait_until_sent
);
87 static void unset_locked_termios(struct termios
*termios
,
89 struct termios
*locked
)
93 #define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z)))
96 printk(KERN_WARNING
"Warning?!? termios_locked is NULL.\n");
100 NOSET_MASK(termios
->c_iflag
, old
->c_iflag
, locked
->c_iflag
);
101 NOSET_MASK(termios
->c_oflag
, old
->c_oflag
, locked
->c_oflag
);
102 NOSET_MASK(termios
->c_cflag
, old
->c_cflag
, locked
->c_cflag
);
103 NOSET_MASK(termios
->c_lflag
, old
->c_lflag
, locked
->c_lflag
);
104 termios
->c_line
= locked
->c_line
? old
->c_line
: termios
->c_line
;
105 for (i
=0; i
< NCCS
; i
++)
106 termios
->c_cc
[i
] = locked
->c_cc
[i
] ?
107 old
->c_cc
[i
] : termios
->c_cc
[i
];
111 * change_termios - update termios values
112 * @tty: tty to update
113 * @new_termios: desired new value
115 * Perform updates to the termios values set on this terminal. There
116 * is a bit of layering violation here with n_tty in terms of the
117 * internal knowledge of this function.
119 * Locking: termios_sem
122 static void change_termios(struct tty_struct
* tty
, struct termios
* new_termios
)
125 struct termios old_termios
= *tty
->termios
;
126 struct tty_ldisc
*ld
;
129 * Perform the actual termios internal changes under lock.
133 /* FIXME: we need to decide on some locking/ordering semantics
134 for the set_termios notification eventually */
135 mutex_lock(&tty
->termios_mutex
);
137 *tty
->termios
= *new_termios
;
138 unset_locked_termios(tty
->termios
, &old_termios
, tty
->termios_locked
);
139 canon_change
= (old_termios
.c_lflag
^ tty
->termios
->c_lflag
) & ICANON
;
141 memset(&tty
->read_flags
, 0, sizeof tty
->read_flags
);
142 tty
->canon_head
= tty
->read_tail
;
148 if (canon_change
&& !L_ICANON(tty
) && tty
->read_cnt
)
149 /* Get characters left over from canonical mode. */
150 wake_up_interruptible(&tty
->read_wait
);
152 /* See if packet mode change of state. */
154 if (tty
->link
&& tty
->link
->packet
) {
155 int old_flow
= ((old_termios
.c_iflag
& IXON
) &&
156 (old_termios
.c_cc
[VSTOP
] == '\023') &&
157 (old_termios
.c_cc
[VSTART
] == '\021'));
158 int new_flow
= (I_IXON(tty
) &&
159 STOP_CHAR(tty
) == '\023' &&
160 START_CHAR(tty
) == '\021');
161 if (old_flow
!= new_flow
) {
162 tty
->ctrl_status
&= ~(TIOCPKT_DOSTOP
| TIOCPKT_NOSTOP
);
164 tty
->ctrl_status
|= TIOCPKT_DOSTOP
;
166 tty
->ctrl_status
|= TIOCPKT_NOSTOP
;
167 wake_up_interruptible(&tty
->link
->read_wait
);
171 if (tty
->driver
->set_termios
)
172 (*tty
->driver
->set_termios
)(tty
, &old_termios
);
174 ld
= tty_ldisc_ref(tty
);
177 (ld
->set_termios
)(tty
, &old_termios
);
180 mutex_unlock(&tty
->termios_mutex
);
184 * set_termios - set termios values for a tty
185 * @tty: terminal device
187 * @opt: option information
189 * Helper function to prepare termios data and run neccessary other
190 * functions before using change_termios to do the actual changes.
193 * Called functions take ldisc and termios_sem locks
196 static int set_termios(struct tty_struct
* tty
, void __user
*arg
, int opt
)
198 struct termios tmp_termios
;
199 struct tty_ldisc
*ld
;
200 int retval
= tty_check_change(tty
);
205 if (opt
& TERMIOS_TERMIO
) {
206 memcpy(&tmp_termios
, tty
->termios
, sizeof(struct termios
));
207 if (user_termio_to_kernel_termios(&tmp_termios
,
208 (struct termio __user
*)arg
))
211 if (user_termios_to_kernel_termios(&tmp_termios
,
212 (struct termios __user
*)arg
))
216 ld
= tty_ldisc_ref(tty
);
219 if ((opt
& TERMIOS_FLUSH
) && ld
->flush_buffer
)
220 ld
->flush_buffer(tty
);
224 if (opt
& TERMIOS_WAIT
) {
225 tty_wait_until_sent(tty
, 0);
226 if (signal_pending(current
))
230 change_termios(tty
, &tmp_termios
);
234 static int get_termio(struct tty_struct
* tty
, struct termio __user
* termio
)
236 if (kernel_termios_to_user_termio(termio
, tty
->termios
))
241 static unsigned long inq_canon(struct tty_struct
* tty
)
245 if (!tty
->canon_data
|| !tty
->read_buf
)
247 head
= tty
->canon_head
;
248 tail
= tty
->read_tail
;
249 nr
= (head
- tail
) & (N_TTY_BUF_SIZE
-1);
250 /* Skip EOF-chars.. */
251 while (head
!= tail
) {
252 if (test_bit(tail
, tty
->read_flags
) &&
253 tty
->read_buf
[tail
] == __DISABLED_CHAR
)
255 tail
= (tail
+1) & (N_TTY_BUF_SIZE
-1);
262 * These are deprecated, but there is limited support..
264 * The "sg_flags" translation is a joke..
266 static int get_sgflags(struct tty_struct
* tty
)
270 if (!(tty
->termios
->c_lflag
& ICANON
)) {
271 if (tty
->termios
->c_lflag
& ISIG
)
272 flags
|= 0x02; /* cbreak */
274 flags
|= 0x20; /* raw */
276 if (tty
->termios
->c_lflag
& ECHO
)
277 flags
|= 0x08; /* echo */
278 if (tty
->termios
->c_oflag
& OPOST
)
279 if (tty
->termios
->c_oflag
& ONLCR
)
280 flags
|= 0x10; /* crmod */
284 static int get_sgttyb(struct tty_struct
* tty
, struct sgttyb __user
* sgttyb
)
288 mutex_lock(&tty
->termios_mutex
);
291 tmp
.sg_erase
= tty
->termios
->c_cc
[VERASE
];
292 tmp
.sg_kill
= tty
->termios
->c_cc
[VKILL
];
293 tmp
.sg_flags
= get_sgflags(tty
);
294 mutex_unlock(&tty
->termios_mutex
);
296 return copy_to_user(sgttyb
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
299 static void set_sgflags(struct termios
* termios
, int flags
)
301 termios
->c_iflag
= ICRNL
| IXON
;
302 termios
->c_oflag
= 0;
303 termios
->c_lflag
= ISIG
| ICANON
;
304 if (flags
& 0x02) { /* cbreak */
305 termios
->c_iflag
= 0;
306 termios
->c_lflag
&= ~ICANON
;
308 if (flags
& 0x08) { /* echo */
309 termios
->c_lflag
|= ECHO
| ECHOE
| ECHOK
|
310 ECHOCTL
| ECHOKE
| IEXTEN
;
312 if (flags
& 0x10) { /* crmod */
313 termios
->c_oflag
|= OPOST
| ONLCR
;
315 if (flags
& 0x20) { /* raw */
316 termios
->c_iflag
= 0;
317 termios
->c_lflag
&= ~(ISIG
| ICANON
);
319 if (!(termios
->c_lflag
& ICANON
)) {
320 termios
->c_cc
[VMIN
] = 1;
321 termios
->c_cc
[VTIME
] = 0;
326 * set_sgttyb - set legacy terminal values
327 * @tty: tty structure
328 * @sgttyb: pointer to old style terminal structure
330 * Updates a terminal from the legacy BSD style terminal information
333 * Locking: termios_sem
336 static int set_sgttyb(struct tty_struct
* tty
, struct sgttyb __user
* sgttyb
)
340 struct termios termios
;
342 retval
= tty_check_change(tty
);
346 if (copy_from_user(&tmp
, sgttyb
, sizeof(tmp
)))
349 mutex_lock(&tty
->termios_mutex
);
350 termios
= *tty
->termios
;
351 termios
.c_cc
[VERASE
] = tmp
.sg_erase
;
352 termios
.c_cc
[VKILL
] = tmp
.sg_kill
;
353 set_sgflags(&termios
, tmp
.sg_flags
);
354 mutex_unlock(&tty
->termios_mutex
);
355 change_termios(tty
, &termios
);
361 static int get_tchars(struct tty_struct
* tty
, struct tchars __user
* tchars
)
365 tmp
.t_intrc
= tty
->termios
->c_cc
[VINTR
];
366 tmp
.t_quitc
= tty
->termios
->c_cc
[VQUIT
];
367 tmp
.t_startc
= tty
->termios
->c_cc
[VSTART
];
368 tmp
.t_stopc
= tty
->termios
->c_cc
[VSTOP
];
369 tmp
.t_eofc
= tty
->termios
->c_cc
[VEOF
];
370 tmp
.t_brkc
= tty
->termios
->c_cc
[VEOL2
]; /* what is brkc anyway? */
371 return copy_to_user(tchars
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
374 static int set_tchars(struct tty_struct
* tty
, struct tchars __user
* tchars
)
378 if (copy_from_user(&tmp
, tchars
, sizeof(tmp
)))
380 tty
->termios
->c_cc
[VINTR
] = tmp
.t_intrc
;
381 tty
->termios
->c_cc
[VQUIT
] = tmp
.t_quitc
;
382 tty
->termios
->c_cc
[VSTART
] = tmp
.t_startc
;
383 tty
->termios
->c_cc
[VSTOP
] = tmp
.t_stopc
;
384 tty
->termios
->c_cc
[VEOF
] = tmp
.t_eofc
;
385 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_brkc
; /* what is brkc anyway? */
391 static int get_ltchars(struct tty_struct
* tty
, struct ltchars __user
* ltchars
)
395 tmp
.t_suspc
= tty
->termios
->c_cc
[VSUSP
];
396 tmp
.t_dsuspc
= tty
->termios
->c_cc
[VSUSP
]; /* what is dsuspc anyway? */
397 tmp
.t_rprntc
= tty
->termios
->c_cc
[VREPRINT
];
398 tmp
.t_flushc
= tty
->termios
->c_cc
[VEOL2
]; /* what is flushc anyway? */
399 tmp
.t_werasc
= tty
->termios
->c_cc
[VWERASE
];
400 tmp
.t_lnextc
= tty
->termios
->c_cc
[VLNEXT
];
401 return copy_to_user(ltchars
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
404 static int set_ltchars(struct tty_struct
* tty
, struct ltchars __user
* ltchars
)
408 if (copy_from_user(&tmp
, ltchars
, sizeof(tmp
)))
411 tty
->termios
->c_cc
[VSUSP
] = tmp
.t_suspc
;
412 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_dsuspc
; /* what is dsuspc anyway? */
413 tty
->termios
->c_cc
[VREPRINT
] = tmp
.t_rprntc
;
414 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_flushc
; /* what is flushc anyway? */
415 tty
->termios
->c_cc
[VWERASE
] = tmp
.t_werasc
;
416 tty
->termios
->c_cc
[VLNEXT
] = tmp
.t_lnextc
;
422 * send_prio_char - send priority character
424 * Send a high priority character to the tty even if stopped
426 * Locking: none for xchar method, write ordering for write method.
429 static int send_prio_char(struct tty_struct
*tty
, char ch
)
431 int was_stopped
= tty
->stopped
;
433 if (tty
->driver
->send_xchar
) {
434 tty
->driver
->send_xchar(tty
, ch
);
438 if (mutex_lock_interruptible(&tty
->atomic_write_lock
))
443 tty
->driver
->write(tty
, &ch
, 1);
446 mutex_unlock(&tty
->atomic_write_lock
);
450 int n_tty_ioctl(struct tty_struct
* tty
, struct file
* file
,
451 unsigned int cmd
, unsigned long arg
)
453 struct tty_struct
* real_tty
;
454 void __user
*p
= (void __user
*)arg
;
456 struct tty_ldisc
*ld
;
458 if (tty
->driver
->type
== TTY_DRIVER_TYPE_PTY
&&
459 tty
->driver
->subtype
== PTY_TYPE_MASTER
)
460 real_tty
= tty
->link
;
467 return get_sgttyb(real_tty
, (struct sgttyb __user
*) arg
);
470 return set_sgttyb(real_tty
, (struct sgttyb __user
*) arg
);
474 return get_tchars(real_tty
, p
);
476 return set_tchars(real_tty
, p
);
480 return get_ltchars(real_tty
, p
);
482 return set_ltchars(real_tty
, p
);
485 if (kernel_termios_to_user_termios((struct termios __user
*)arg
, real_tty
->termios
))
489 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
);
491 return set_termios(real_tty
, p
, TERMIOS_WAIT
);
493 return set_termios(real_tty
, p
, 0);
495 return get_termio(real_tty
, p
);
497 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
| TERMIOS_TERMIO
);
499 return set_termios(real_tty
, p
, TERMIOS_WAIT
| TERMIOS_TERMIO
);
501 return set_termios(real_tty
, p
, TERMIOS_TERMIO
);
503 retval
= tty_check_change(tty
);
508 if (!tty
->flow_stopped
) {
509 tty
->flow_stopped
= 1;
514 if (tty
->flow_stopped
) {
515 tty
->flow_stopped
= 0;
520 if (STOP_CHAR(tty
) != __DISABLED_CHAR
)
521 return send_prio_char(tty
, STOP_CHAR(tty
));
524 if (START_CHAR(tty
) != __DISABLED_CHAR
)
525 return send_prio_char(tty
, START_CHAR(tty
));
532 retval
= tty_check_change(tty
);
536 ld
= tty_ldisc_ref(tty
);
539 if (ld
&& ld
->flush_buffer
)
540 ld
->flush_buffer(tty
);
543 if (ld
&& ld
->flush_buffer
)
544 ld
->flush_buffer(tty
);
547 if (tty
->driver
->flush_buffer
)
548 tty
->driver
->flush_buffer(tty
);
557 return put_user(tty
->driver
->chars_in_buffer
?
558 tty
->driver
->chars_in_buffer(tty
) : 0,
561 retval
= tty
->read_cnt
;
563 retval
= inq_canon(tty
);
564 return put_user(retval
, (unsigned int __user
*) arg
);
566 if (kernel_termios_to_user_termios((struct termios __user
*)arg
, real_tty
->termios_locked
))
571 if (!capable(CAP_SYS_ADMIN
))
573 if (user_termios_to_kernel_termios(real_tty
->termios_locked
, (struct termios __user
*) arg
))
581 if (tty
->driver
->type
!= TTY_DRIVER_TYPE_PTY
||
582 tty
->driver
->subtype
!= PTY_TYPE_MASTER
)
584 if (get_user(pktmode
, (int __user
*) arg
))
589 tty
->link
->ctrl_status
= 0;
596 return put_user(C_CLOCAL(tty
) ? 1 : 0, (int __user
*)arg
);
598 if (get_user(arg
, (unsigned int __user
*) arg
))
600 mutex_lock(&tty
->termios_mutex
);
601 tty
->termios
->c_cflag
=
602 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
604 mutex_unlock(&tty
->termios_mutex
);
611 EXPORT_SYMBOL(n_tty_ioctl
);