Blame view
drivers/tty/tty_ioctl.c
23.7 KB
e3b3d0f54 tty: add SPDX ide... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 10 11 12 |
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds * * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines * which can be dynamically activated and de-activated by the line * discipline handling modules (like SLIP). */ #include <linux/types.h> #include <linux/termios.h> #include <linux/errno.h> |
174cd4b1e sched/headers: Pr... |
13 |
#include <linux/sched/signal.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 17 18 19 20 21 |
#include <linux/kernel.h> #include <linux/major.h> #include <linux/tty.h> #include <linux/fcntl.h> #include <linux/string.h> #include <linux/mm.h> #include <linux/module.h> #include <linux/bitops.h> |
5785c95ba [PATCH] tty: make... |
22 |
#include <linux/mutex.h> |
8193c4290 tty: Support comp... |
23 |
#include <linux/compat.h> |
1da177e4c Linux-2.6.12-rc2 |
24 25 |
#include <asm/io.h> |
7c0f6ba68 Replace <asm/uacc... |
26 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
27 28 |
#undef TTY_DEBUG_WAIT_UNTIL_SENT |
ff8339dc1 tty: Replace inli... |
29 30 31 32 33 |
#ifdef TTY_DEBUG_WAIT_UNTIL_SENT # define tty_debug_wait_until_sent(tty, f, args...) tty_debug(tty, f, ##args) #else # define tty_debug_wait_until_sent(tty, f, args...) do {} while (0) #endif |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 38 39 40 41 |
#undef DEBUG /* * Internal flag options for termios setting behavior */ #define TERMIOS_FLUSH 1 #define TERMIOS_WAIT 2 #define TERMIOS_TERMIO 4 |
edc6afc54 [PATCH] tty: swit... |
42 |
#define TERMIOS_OLD 8 |
1da177e4c Linux-2.6.12-rc2 |
43 |
|
af9b897ee [PATCH] tty layer... |
44 |
|
d81ed1030 tty: Remove more ... |
45 46 47 48 49 50 51 52 |
/** * tty_chars_in_buffer - characters pending * @tty: terminal * * Return the number of bytes of data in the device private * output queue. If no private method is supplied there is assumed * to be no queue on the device. */ |
f34d7a5b7 tty: The big oper... |
53 54 55 56 57 58 59 |
int tty_chars_in_buffer(struct tty_struct *tty) { if (tty->ops->chars_in_buffer) return tty->ops->chars_in_buffer(tty); else return 0; } |
f34d7a5b7 tty: The big oper... |
60 |
EXPORT_SYMBOL(tty_chars_in_buffer); |
d81ed1030 tty: Remove more ... |
61 62 63 64 65 66 67 68 69 70 71 |
/** * tty_write_room - write queue space * @tty: terminal * * Return the number of bytes that can be queued to this device * at the present time. The result should be treated as a guarantee * and the driver cannot offer a value it later shrinks by more than * the number of bytes written. If no method is provided 2K is always * returned and data may be lost as there will be no flow control. */ |
f34d7a5b7 tty: The big oper... |
72 73 74 75 76 77 |
int tty_write_room(struct tty_struct *tty) { if (tty->ops->write_room) return tty->ops->write_room(tty); return 2048; } |
f34d7a5b7 tty: The big oper... |
78 |
EXPORT_SYMBOL(tty_write_room); |
d81ed1030 tty: Remove more ... |
79 80 81 82 83 84 85 86 |
/** * tty_driver_flush_buffer - discard internal buffer * @tty: terminal * * Discard the internal output buffer for this device. If no method * is provided then either the buffer cannot be hardware flushed or * there is no buffer driver side. */ |
f34d7a5b7 tty: The big oper... |
87 88 89 90 91 |
void tty_driver_flush_buffer(struct tty_struct *tty) { if (tty->ops->flush_buffer) tty->ops->flush_buffer(tty); } |
f34d7a5b7 tty: The big oper... |
92 |
EXPORT_SYMBOL(tty_driver_flush_buffer); |
d81ed1030 tty: Remove more ... |
93 94 95 96 97 |
/** * tty_throttle - flow control * @tty: terminal * * Indicate that a tty should stop transmitting data down the stack. |
6a1c0680c tty: Convert term... |
98 |
* Takes the termios rwsem to protect against parallel throttle/unthrottle |
38db89799 tty: throttling r... |
99 100 |
* and also to ensure the driver can consistently reference its own * termios data at this point when implementing software flow control. |
d81ed1030 tty: Remove more ... |
101 |
*/ |
39c2e60f8 tty: add throttle... |
102 103 |
void tty_throttle(struct tty_struct *tty) { |
6a1c0680c tty: Convert term... |
104 |
down_write(&tty->termios_rwsem); |
39c2e60f8 tty: add throttle... |
105 106 107 108 |
/* check TTY_THROTTLED first so it indicates our state */ if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && tty->ops->throttle) tty->ops->throttle(tty); |
70bc12647 tty: Add safe tty... |
109 |
tty->flow_change = 0; |
6a1c0680c tty: Convert term... |
110 |
up_write(&tty->termios_rwsem); |
39c2e60f8 tty: add throttle... |
111 112 |
} EXPORT_SYMBOL(tty_throttle); |
d81ed1030 tty: Remove more ... |
113 114 115 116 117 |
/** * tty_unthrottle - flow control * @tty: terminal * * Indicate that a tty may continue transmitting data down the stack. |
6a1c0680c tty: Convert term... |
118 |
* Takes the termios rwsem to protect against parallel throttle/unthrottle |
38db89799 tty: throttling r... |
119 120 121 122 123 |
* and also to ensure the driver can consistently reference its own * termios data at this point when implementing software flow control. * * Drivers should however remember that the stack can issue a throttle, * then change flow control method, then unthrottle. |
d81ed1030 tty: Remove more ... |
124 |
*/ |
39c2e60f8 tty: add throttle... |
125 126 |
void tty_unthrottle(struct tty_struct *tty) { |
6a1c0680c tty: Convert term... |
127 |
down_write(&tty->termios_rwsem); |
39c2e60f8 tty: add throttle... |
128 129 130 |
if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && tty->ops->unthrottle) tty->ops->unthrottle(tty); |
70bc12647 tty: Add safe tty... |
131 |
tty->flow_change = 0; |
6a1c0680c tty: Convert term... |
132 |
up_write(&tty->termios_rwsem); |
39c2e60f8 tty: add throttle... |
133 134 |
} EXPORT_SYMBOL(tty_unthrottle); |
f34d7a5b7 tty: The big oper... |
135 |
|
af9b897ee [PATCH] tty layer... |
136 |
/** |
70bc12647 tty: Add safe tty... |
137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
* tty_throttle_safe - flow control * @tty: terminal * * Similar to tty_throttle() but will only attempt throttle * if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental * throttle due to race conditions when throttling is conditional * on factors evaluated prior to throttling. * * Returns 0 if tty is throttled (or was already throttled) */ int tty_throttle_safe(struct tty_struct *tty) { int ret = 0; |
d8c1f929a tty: Only guarant... |
151 |
mutex_lock(&tty->throttle_mutex); |
97ef38b82 tty: Replace TTY_... |
152 |
if (!tty_throttled(tty)) { |
70bc12647 tty: Add safe tty... |
153 154 155 |
if (tty->flow_change != TTY_THROTTLE_SAFE) ret = 1; else { |
579a00a5c tty: Fix unsafe b... |
156 |
set_bit(TTY_THROTTLED, &tty->flags); |
70bc12647 tty: Add safe tty... |
157 158 159 160 |
if (tty->ops->throttle) tty->ops->throttle(tty); } } |
d8c1f929a tty: Only guarant... |
161 |
mutex_unlock(&tty->throttle_mutex); |
70bc12647 tty: Add safe tty... |
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
return ret; } /** * tty_unthrottle_safe - flow control * @tty: terminal * * Similar to tty_unthrottle() but will only attempt unthrottle * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental * unthrottle due to race conditions when unthrottling is conditional * on factors evaluated prior to unthrottling. * * Returns 0 if tty is unthrottled (or was already unthrottled) */ int tty_unthrottle_safe(struct tty_struct *tty) { int ret = 0; |
d8c1f929a tty: Only guarant... |
181 |
mutex_lock(&tty->throttle_mutex); |
97ef38b82 tty: Replace TTY_... |
182 |
if (tty_throttled(tty)) { |
70bc12647 tty: Add safe tty... |
183 184 185 |
if (tty->flow_change != TTY_UNTHROTTLE_SAFE) ret = 1; else { |
579a00a5c tty: Fix unsafe b... |
186 |
clear_bit(TTY_THROTTLED, &tty->flags); |
70bc12647 tty: Add safe tty... |
187 188 189 190 |
if (tty->ops->unthrottle) tty->ops->unthrottle(tty); } } |
d8c1f929a tty: Only guarant... |
191 |
mutex_unlock(&tty->throttle_mutex); |
70bc12647 tty: Add safe tty... |
192 193 194 195 196 |
return ret; } /** |
af9b897ee [PATCH] tty layer... |
197 198 199 200 201 202 203 204 205 |
* tty_wait_until_sent - wait for I/O to finish * @tty: tty we are waiting for * @timeout: how long we will wait * * Wait for characters pending in a tty driver to hit the wire, or * for a timeout to occur (eg due to flow control) * * Locking: none */ |
355d95a1c tty_ioctl: drag s... |
206 |
void tty_wait_until_sent(struct tty_struct *tty, long timeout) |
1da177e4c Linux-2.6.12-rc2 |
207 |
{ |
d435cefe9 tty: Remove __fun... |
208 209 |
tty_debug_wait_until_sent(tty, "wait until sent, timeout=%ld ", timeout); |
ff8339dc1 tty: Replace inli... |
210 |
|
1da177e4c Linux-2.6.12-rc2 |
211 212 |
if (!timeout) timeout = MAX_SCHEDULE_TIMEOUT; |
79fbf4a55 TTY: fix tty_wait... |
213 |
|
c37bc682e TTY: fix tty_wait... |
214 215 216 |
timeout = wait_event_interruptible_timeout(tty->write_wait, !tty_chars_in_buffer(tty), timeout); if (timeout <= 0) |
79fbf4a55 TTY: fix tty_wait... |
217 |
return; |
79fbf4a55 TTY: fix tty_wait... |
218 219 220 221 222 223 |
if (timeout == MAX_SCHEDULE_TIMEOUT) timeout = 0; if (tty->ops->wait_until_sent) tty->ops->wait_until_sent(tty, timeout); |
1da177e4c Linux-2.6.12-rc2 |
224 |
} |
1da177e4c Linux-2.6.12-rc2 |
225 |
EXPORT_SYMBOL(tty_wait_until_sent); |
d81ed1030 tty: Remove more ... |
226 227 228 229 |
/* * Termios Helper Methods */ |
d97ba9cda tty: core: Refact... |
230 |
static void unset_locked_termios(struct tty_struct *tty, struct ktermios *old) |
1da177e4c Linux-2.6.12-rc2 |
231 |
{ |
d97ba9cda tty: core: Refact... |
232 233 |
struct ktermios *termios = &tty->termios; struct ktermios *locked = &tty->termios_locked; |
1da177e4c Linux-2.6.12-rc2 |
234 |
int i; |
355d95a1c tty_ioctl: drag s... |
235 236 |
#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z))) |
1da177e4c Linux-2.6.12-rc2 |
237 |
|
1da177e4c Linux-2.6.12-rc2 |
238 239 240 241 242 |
NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag); NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag); NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag); NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag); termios->c_line = locked->c_line ? old->c_line : termios->c_line; |
355d95a1c tty_ioctl: drag s... |
243 |
for (i = 0; i < NCCS; i++) |
1da177e4c Linux-2.6.12-rc2 |
244 245 |
termios->c_cc[i] = locked->c_cc[i] ? old->c_cc[i] : termios->c_cc[i]; |
edc6afc54 [PATCH] tty: swit... |
246 |
/* FIXME: What should we do for i/ospeed */ |
1da177e4c Linux-2.6.12-rc2 |
247 |
} |
edc6afc54 [PATCH] tty: swit... |
248 |
/** |
5f519d728 tty: expose new m... |
249 250 251 252 |
* tty_termios_copy_hw - copy hardware settings * @new: New termios * @old: Old termios * |
25985edce Fix common misspe... |
253 |
* Propagate the hardware specific terminal setting bits from |
5f519d728 tty: expose new m... |
254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
* the old termios structure to the new one. This is used in cases * where the hardware does not support reconfiguration or as a helper * in some cases where only minimal reconfiguration is supported */ void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old) { /* The bits a dumb device handles in software. Smart devices need to always provide a set_termios method */ new->c_cflag &= HUPCL | CREAD | CLOCAL; new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL); new->c_ispeed = old->c_ispeed; new->c_ospeed = old->c_ospeed; } |
5f519d728 tty: expose new m... |
268 269 270 |
EXPORT_SYMBOL(tty_termios_copy_hw); /** |
bf5e5834b pl2303: Fix mode ... |
271 272 273 274 275 276 277 |
* tty_termios_hw_change - check for setting change * @a: termios * @b: termios to compare * * Check if any of the bits that affect a dumb device have changed * between the two termios structures, or a speed change is needed. */ |
7b0c6b38c tty: add missing ... |
278 |
int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b) |
bf5e5834b pl2303: Fix mode ... |
279 280 281 282 283 284 285 286 287 288 |
{ if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) return 1; if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL)) return 1; return 0; } EXPORT_SYMBOL(tty_termios_hw_change); /** |
8d075b199 tty: add a helper... |
289 |
* tty_set_termios - update termios values |
af9b897ee [PATCH] tty layer... |
290 291 292 |
* @tty: tty to update * @new_termios: desired new value * |
dbfcd851a tty: Move pty-spe... |
293 |
* Perform updates to the termios values set on this terminal. |
6460fbbf4 tty: WARN for att... |
294 295 |
* A master pty's termios should never be set. * |
6a1c0680c tty: Convert term... |
296 |
* Locking: termios_rwsem |
af9b897ee [PATCH] tty layer... |
297 |
*/ |
b00f5c2dc tty: Re-add exter... |
298 |
int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) |
1da177e4c Linux-2.6.12-rc2 |
299 |
{ |
978e595f8 tty/serial: lay t... |
300 |
struct ktermios old_termios; |
1da177e4c Linux-2.6.12-rc2 |
301 |
struct tty_ldisc *ld; |
355d95a1c tty_ioctl: drag s... |
302 |
|
6460fbbf4 tty: WARN for att... |
303 304 |
WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER); |
1da177e4c Linux-2.6.12-rc2 |
305 306 307 |
/* * Perform the actual termios internal changes under lock. */ |
355d95a1c tty_ioctl: drag s... |
308 |
|
1da177e4c Linux-2.6.12-rc2 |
309 310 311 |
/* FIXME: we need to decide on some locking/ordering semantics for the set_termios notification eventually */ |
6a1c0680c tty: Convert term... |
312 |
down_write(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
313 314 |
old_termios = tty->termios; tty->termios = *new_termios; |
d97ba9cda tty: core: Refact... |
315 |
unset_locked_termios(tty, &old_termios); |
1da177e4c Linux-2.6.12-rc2 |
316 |
|
f34d7a5b7 tty: The big oper... |
317 |
if (tty->ops->set_termios) |
c961bfb17 tty: Call methods... |
318 |
tty->ops->set_termios(tty, &old_termios); |
5f519d728 tty: expose new m... |
319 |
else |
adc8d746c tty: move the ter... |
320 |
tty_termios_copy_hw(&tty->termios, &old_termios); |
1da177e4c Linux-2.6.12-rc2 |
321 322 323 |
ld = tty_ldisc_ref(tty); if (ld != NULL) { |
a352def21 tty: Ldisc revamp |
324 |
if (ld->ops->set_termios) |
c961bfb17 tty: Call methods... |
325 |
ld->ops->set_termios(tty, &old_termios); |
1da177e4c Linux-2.6.12-rc2 |
326 327 |
tty_ldisc_deref(ld); } |
6a1c0680c tty: Convert term... |
328 |
up_write(&tty->termios_rwsem); |
8d075b199 tty: add a helper... |
329 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
330 |
} |
b00f5c2dc tty: Re-add exter... |
331 |
EXPORT_SYMBOL_GPL(tty_set_termios); |
1da177e4c Linux-2.6.12-rc2 |
332 |
|
af9b897ee [PATCH] tty layer... |
333 334 335 336 337 338 |
/** * set_termios - set termios values for a tty * @tty: terminal device * @arg: user data * @opt: option information * |
3a4fa0a25 Fix misspellings ... |
339 |
* Helper function to prepare termios data and run necessary other |
8d075b199 tty: add a helper... |
340 |
* functions before using tty_set_termios to do the actual changes. |
af9b897ee [PATCH] tty layer... |
341 342 |
* * Locking: |
6a1c0680c tty: Convert term... |
343 |
* Called functions take ldisc and termios_rwsem locks |
af9b897ee [PATCH] tty layer... |
344 |
*/ |
355d95a1c tty_ioctl: drag s... |
345 |
static int set_termios(struct tty_struct *tty, void __user *arg, int opt) |
1da177e4c Linux-2.6.12-rc2 |
346 |
{ |
edc6afc54 [PATCH] tty: swit... |
347 |
struct ktermios tmp_termios; |
1da177e4c Linux-2.6.12-rc2 |
348 349 350 351 352 |
struct tty_ldisc *ld; int retval = tty_check_change(tty); if (retval) return retval; |
6a1c0680c tty: Convert term... |
353 |
down_read(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
354 |
tmp_termios = tty->termios; |
6a1c0680c tty: Convert term... |
355 |
up_read(&tty->termios_rwsem); |
64bb6c5e1 [PATCH] tty_ioctl... |
356 |
|
1da177e4c Linux-2.6.12-rc2 |
357 |
if (opt & TERMIOS_TERMIO) { |
1da177e4c Linux-2.6.12-rc2 |
358 359 360 |
if (user_termio_to_kernel_termios(&tmp_termios, (struct termio __user *)arg)) return -EFAULT; |
edc6afc54 [PATCH] tty: swit... |
361 362 |
#ifdef TCGETS2 } else if (opt & TERMIOS_OLD) { |
edc6afc54 [PATCH] tty: swit... |
363 |
if (user_termios_to_kernel_termios_1(&tmp_termios, |
64bb6c5e1 [PATCH] tty_ioctl... |
364 |
(struct termios __user *)arg)) |
edc6afc54 [PATCH] tty: swit... |
365 |
return -EFAULT; |
1da177e4c Linux-2.6.12-rc2 |
366 367 |
} else { if (user_termios_to_kernel_termios(&tmp_termios, |
64bb6c5e1 [PATCH] tty_ioctl... |
368 |
(struct termios2 __user *)arg)) |
1da177e4c Linux-2.6.12-rc2 |
369 370 |
return -EFAULT; } |
64bb6c5e1 [PATCH] tty_ioctl... |
371 372 373 374 375 |
#else } else if (user_termios_to_kernel_termios(&tmp_termios, (struct termios __user *)arg)) return -EFAULT; #endif |
1da177e4c Linux-2.6.12-rc2 |
376 |
|
355d95a1c tty_ioctl: drag s... |
377 378 |
/* If old style Bfoo values are used then load c_ispeed/c_ospeed * with the real speed so its unconditionally usable */ |
edc6afc54 [PATCH] tty: swit... |
379 380 |
tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); |
1da177e4c Linux-2.6.12-rc2 |
381 |
ld = tty_ldisc_ref(tty); |
355d95a1c tty_ioctl: drag s... |
382 |
|
1da177e4c Linux-2.6.12-rc2 |
383 |
if (ld != NULL) { |
a352def21 tty: Ldisc revamp |
384 385 |
if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) ld->ops->flush_buffer(tty); |
1da177e4c Linux-2.6.12-rc2 |
386 387 |
tty_ldisc_deref(ld); } |
355d95a1c tty_ioctl: drag s... |
388 |
|
1da177e4c Linux-2.6.12-rc2 |
389 390 391 |
if (opt & TERMIOS_WAIT) { tty_wait_until_sent(tty, 0); if (signal_pending(current)) |
183d95cdd tty: set_termios/... |
392 |
return -ERESTARTSYS; |
1da177e4c Linux-2.6.12-rc2 |
393 |
} |
8d075b199 tty: add a helper... |
394 |
tty_set_termios(tty, &tmp_termios); |
5f519d728 tty: expose new m... |
395 396 397 398 399 |
/* FIXME: Arguably if tmp_termios == tty->termios AND the actual requested termios was not tmp_termios then we may want to return an error as no user requested change has succeeded */ |
1da177e4c Linux-2.6.12-rc2 |
400 401 |
return 0; } |
26a2e20f4 tty: Untangle ter... |
402 403 |
static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) { |
6a1c0680c tty: Convert term... |
404 |
down_read(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
405 |
*kterm = tty->termios; |
6a1c0680c tty: Convert term... |
406 |
up_read(&tty->termios_rwsem); |
26a2e20f4 tty: Untangle ter... |
407 408 409 410 |
} static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) { |
6a1c0680c tty: Convert term... |
411 |
down_read(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
412 |
*kterm = tty->termios_locked; |
6a1c0680c tty: Convert term... |
413 |
up_read(&tty->termios_rwsem); |
26a2e20f4 tty: Untangle ter... |
414 |
} |
355d95a1c tty_ioctl: drag s... |
415 |
static int get_termio(struct tty_struct *tty, struct termio __user *termio) |
1da177e4c Linux-2.6.12-rc2 |
416 |
{ |
26a2e20f4 tty: Untangle ter... |
417 418 419 |
struct ktermios kterm; copy_termios(tty, &kterm); if (kernel_termios_to_user_termio(termio, &kterm)) |
1da177e4c Linux-2.6.12-rc2 |
420 421 422 |
return -EFAULT; return 0; } |
1d65b4a08 tty: Add termiox |
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
#ifdef TCGETX /** * set_termiox - set termiox fields if possible * @tty: terminal * @arg: termiox structure from user * @opt: option flags for ioctl type * * Implement the device calling points for the SYS5 termiox ioctl * interface in Linux */ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) { struct termiox tnew; struct tty_ldisc *ld; if (tty->termiox == NULL) return -EINVAL; if (copy_from_user(&tnew, arg, sizeof(struct termiox))) return -EFAULT; ld = tty_ldisc_ref(tty); if (ld != NULL) { if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) ld->ops->flush_buffer(tty); tty_ldisc_deref(ld); } if (opt & TERMIOS_WAIT) { tty_wait_until_sent(tty, 0); if (signal_pending(current)) |
183d95cdd tty: set_termios/... |
455 |
return -ERESTARTSYS; |
1d65b4a08 tty: Add termiox |
456 |
} |
6a1c0680c tty: Convert term... |
457 |
down_write(&tty->termios_rwsem); |
1d65b4a08 tty: Add termiox |
458 459 |
if (tty->ops->set_termiox) tty->ops->set_termiox(tty, &tnew); |
6a1c0680c tty: Convert term... |
460 |
up_write(&tty->termios_rwsem); |
1d65b4a08 tty: Add termiox |
461 462 463 464 |
return 0; } #endif |
1da177e4c Linux-2.6.12-rc2 |
465 466 467 468 469 470 471 |
#ifdef TIOCGETP /* * These are deprecated, but there is limited support.. * * The "sg_flags" translation is a joke.. */ |
355d95a1c tty_ioctl: drag s... |
472 |
static int get_sgflags(struct tty_struct *tty) |
1da177e4c Linux-2.6.12-rc2 |
473 474 |
{ int flags = 0; |
9db276f8f tty: Use termios ... |
475 476 |
if (!L_ICANON(tty)) { if (L_ISIG(tty)) |
1da177e4c Linux-2.6.12-rc2 |
477 478 479 480 |
flags |= 0x02; /* cbreak */ else flags |= 0x20; /* raw */ } |
9db276f8f tty: Use termios ... |
481 |
if (L_ECHO(tty)) |
1da177e4c Linux-2.6.12-rc2 |
482 |
flags |= 0x08; /* echo */ |
9db276f8f tty: Use termios ... |
483 484 |
if (O_OPOST(tty)) if (O_ONLCR(tty)) |
1da177e4c Linux-2.6.12-rc2 |
485 486 487 |
flags |= 0x10; /* crmod */ return flags; } |
355d95a1c tty_ioctl: drag s... |
488 |
static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) |
1da177e4c Linux-2.6.12-rc2 |
489 490 |
{ struct sgttyb tmp; |
6a1c0680c tty: Convert term... |
491 |
down_read(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
492 493 494 495 |
tmp.sg_ispeed = tty->termios.c_ispeed; tmp.sg_ospeed = tty->termios.c_ospeed; tmp.sg_erase = tty->termios.c_cc[VERASE]; tmp.sg_kill = tty->termios.c_cc[VKILL]; |
1da177e4c Linux-2.6.12-rc2 |
496 |
tmp.sg_flags = get_sgflags(tty); |
6a1c0680c tty: Convert term... |
497 |
up_read(&tty->termios_rwsem); |
355d95a1c tty_ioctl: drag s... |
498 |
|
1da177e4c Linux-2.6.12-rc2 |
499 500 |
return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; } |
355d95a1c tty_ioctl: drag s... |
501 |
static void set_sgflags(struct ktermios *termios, int flags) |
1da177e4c Linux-2.6.12-rc2 |
502 |
{ |
9833facf9 tty: Fix up PPC f... |
503 504 505 |
termios->c_iflag = ICRNL | IXON; termios->c_oflag = 0; termios->c_lflag = ISIG | ICANON; |
1da177e4c Linux-2.6.12-rc2 |
506 |
if (flags & 0x02) { /* cbreak */ |
9833facf9 tty: Fix up PPC f... |
507 508 |
termios->c_iflag = 0; termios->c_lflag &= ~ICANON; |
1da177e4c Linux-2.6.12-rc2 |
509 510 |
} if (flags & 0x08) { /* echo */ |
9833facf9 tty: Fix up PPC f... |
511 |
termios->c_lflag |= ECHO | ECHOE | ECHOK | |
1da177e4c Linux-2.6.12-rc2 |
512 513 514 |
ECHOCTL | ECHOKE | IEXTEN; } if (flags & 0x10) { /* crmod */ |
9833facf9 tty: Fix up PPC f... |
515 |
termios->c_oflag |= OPOST | ONLCR; |
1da177e4c Linux-2.6.12-rc2 |
516 517 |
} if (flags & 0x20) { /* raw */ |
9833facf9 tty: Fix up PPC f... |
518 519 |
termios->c_iflag = 0; termios->c_lflag &= ~(ISIG | ICANON); |
1da177e4c Linux-2.6.12-rc2 |
520 |
} |
9833facf9 tty: Fix up PPC f... |
521 522 523 |
if (!(termios->c_lflag & ICANON)) { termios->c_cc[VMIN] = 1; termios->c_cc[VTIME] = 0; |
1da177e4c Linux-2.6.12-rc2 |
524 525 |
} } |
af9b897ee [PATCH] tty layer... |
526 527 528 529 530 531 532 533 |
/** * set_sgttyb - set legacy terminal values * @tty: tty structure * @sgttyb: pointer to old style terminal structure * * Updates a terminal from the legacy BSD style terminal information * structure. * |
6a1c0680c tty: Convert term... |
534 |
* Locking: termios_rwsem |
af9b897ee [PATCH] tty layer... |
535 |
*/ |
355d95a1c tty_ioctl: drag s... |
536 |
static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) |
1da177e4c Linux-2.6.12-rc2 |
537 538 539 |
{ int retval; struct sgttyb tmp; |
edc6afc54 [PATCH] tty: swit... |
540 |
struct ktermios termios; |
1da177e4c Linux-2.6.12-rc2 |
541 542 543 544 |
retval = tty_check_change(tty); if (retval) return retval; |
355d95a1c tty_ioctl: drag s... |
545 |
|
1da177e4c Linux-2.6.12-rc2 |
546 547 |
if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) return -EFAULT; |
6a1c0680c tty: Convert term... |
548 |
down_write(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
549 |
termios = tty->termios; |
1da177e4c Linux-2.6.12-rc2 |
550 551 552 |
termios.c_cc[VERASE] = tmp.sg_erase; termios.c_cc[VKILL] = tmp.sg_kill; set_sgflags(&termios, tmp.sg_flags); |
edc6afc54 [PATCH] tty: swit... |
553 554 |
/* Try and encode into Bfoo format */ #ifdef BOTHER |
355d95a1c tty_ioctl: drag s... |
555 556 |
tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed); |
edc6afc54 [PATCH] tty: swit... |
557 |
#endif |
6a1c0680c tty: Convert term... |
558 |
up_write(&tty->termios_rwsem); |
8d075b199 tty: add a helper... |
559 |
tty_set_termios(tty, &termios); |
1da177e4c Linux-2.6.12-rc2 |
560 561 562 563 564 |
return 0; } #endif #ifdef TIOCGETC |
355d95a1c tty_ioctl: drag s... |
565 |
static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) |
1da177e4c Linux-2.6.12-rc2 |
566 567 |
{ struct tchars tmp; |
6a1c0680c tty: Convert term... |
568 |
down_read(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
569 570 571 572 573 574 |
tmp.t_intrc = tty->termios.c_cc[VINTR]; tmp.t_quitc = tty->termios.c_cc[VQUIT]; tmp.t_startc = tty->termios.c_cc[VSTART]; tmp.t_stopc = tty->termios.c_cc[VSTOP]; tmp.t_eofc = tty->termios.c_cc[VEOF]; tmp.t_brkc = tty->termios.c_cc[VEOL2]; /* what is brkc anyway? */ |
6a1c0680c tty: Convert term... |
575 |
up_read(&tty->termios_rwsem); |
1da177e4c Linux-2.6.12-rc2 |
576 577 |
return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; } |
355d95a1c tty_ioctl: drag s... |
578 |
static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) |
1da177e4c Linux-2.6.12-rc2 |
579 580 581 582 583 |
{ struct tchars tmp; if (copy_from_user(&tmp, tchars, sizeof(tmp))) return -EFAULT; |
6a1c0680c tty: Convert term... |
584 |
down_write(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
585 586 587 588 589 590 |
tty->termios.c_cc[VINTR] = tmp.t_intrc; tty->termios.c_cc[VQUIT] = tmp.t_quitc; tty->termios.c_cc[VSTART] = tmp.t_startc; tty->termios.c_cc[VSTOP] = tmp.t_stopc; tty->termios.c_cc[VEOF] = tmp.t_eofc; tty->termios.c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ |
6a1c0680c tty: Convert term... |
591 |
up_write(&tty->termios_rwsem); |
1da177e4c Linux-2.6.12-rc2 |
592 593 594 595 596 |
return 0; } #endif #ifdef TIOCGLTC |
355d95a1c tty_ioctl: drag s... |
597 |
static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) |
1da177e4c Linux-2.6.12-rc2 |
598 599 |
{ struct ltchars tmp; |
6a1c0680c tty: Convert term... |
600 |
down_read(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
601 |
tmp.t_suspc = tty->termios.c_cc[VSUSP]; |
355d95a1c tty_ioctl: drag s... |
602 |
/* what is dsuspc anyway? */ |
adc8d746c tty: move the ter... |
603 604 |
tmp.t_dsuspc = tty->termios.c_cc[VSUSP]; tmp.t_rprntc = tty->termios.c_cc[VREPRINT]; |
355d95a1c tty_ioctl: drag s... |
605 |
/* what is flushc anyway? */ |
adc8d746c tty: move the ter... |
606 607 608 |
tmp.t_flushc = tty->termios.c_cc[VEOL2]; tmp.t_werasc = tty->termios.c_cc[VWERASE]; tmp.t_lnextc = tty->termios.c_cc[VLNEXT]; |
6a1c0680c tty: Convert term... |
609 |
up_read(&tty->termios_rwsem); |
1da177e4c Linux-2.6.12-rc2 |
610 611 |
return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; } |
355d95a1c tty_ioctl: drag s... |
612 |
static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) |
1da177e4c Linux-2.6.12-rc2 |
613 614 615 616 617 |
{ struct ltchars tmp; if (copy_from_user(&tmp, ltchars, sizeof(tmp))) return -EFAULT; |
6a1c0680c tty: Convert term... |
618 |
down_write(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
619 |
tty->termios.c_cc[VSUSP] = tmp.t_suspc; |
355d95a1c tty_ioctl: drag s... |
620 |
/* what is dsuspc anyway? */ |
adc8d746c tty: move the ter... |
621 622 |
tty->termios.c_cc[VEOL2] = tmp.t_dsuspc; tty->termios.c_cc[VREPRINT] = tmp.t_rprntc; |
355d95a1c tty_ioctl: drag s... |
623 |
/* what is flushc anyway? */ |
adc8d746c tty: move the ter... |
624 625 626 |
tty->termios.c_cc[VEOL2] = tmp.t_flushc; tty->termios.c_cc[VWERASE] = tmp.t_werasc; tty->termios.c_cc[VLNEXT] = tmp.t_lnextc; |
6a1c0680c tty: Convert term... |
627 |
up_write(&tty->termios_rwsem); |
1da177e4c Linux-2.6.12-rc2 |
628 629 630 |
return 0; } #endif |
af9b897ee [PATCH] tty layer... |
631 |
/** |
1c2630ccf tty_ioctl: soft c... |
632 633 634 635 636 |
* tty_change_softcar - carrier change ioctl helper * @tty: tty to update * @arg: enable/disable CLOCAL * * Perform a change to the CLOCAL state and call into the driver |
6a1c0680c tty: Convert term... |
637 |
* layer to make it visible. All done with the termios rwsem |
1c2630ccf tty_ioctl: soft c... |
638 639 640 641 642 643 |
*/ static int tty_change_softcar(struct tty_struct *tty, int arg) { int ret = 0; int bit = arg ? CLOCAL : 0; |
f34d7a5b7 tty: The big oper... |
644 |
struct ktermios old; |
1c2630ccf tty_ioctl: soft c... |
645 |
|
6a1c0680c tty: Convert term... |
646 |
down_write(&tty->termios_rwsem); |
adc8d746c tty: move the ter... |
647 648 649 |
old = tty->termios; tty->termios.c_cflag &= ~CLOCAL; tty->termios.c_cflag |= bit; |
f34d7a5b7 tty: The big oper... |
650 651 |
if (tty->ops->set_termios) tty->ops->set_termios(tty, &old); |
9db276f8f tty: Use termios ... |
652 |
if (C_CLOCAL(tty) != bit) |
1c2630ccf tty_ioctl: soft c... |
653 |
ret = -EINVAL; |
6a1c0680c tty: Convert term... |
654 |
up_write(&tty->termios_rwsem); |
1c2630ccf tty_ioctl: soft c... |
655 656 657 658 |
return ret; } /** |
0fc00e244 [TTY]: Fix networ... |
659 660 661 662 663 664 665 666 667 668 |
* tty_mode_ioctl - mode related ioctls * @tty: tty for the ioctl * @file: file pointer for the tty * @cmd: command * @arg: ioctl argument * * Perform non line discipline specific mode control ioctls. This * is designed to be called by line disciplines to ensure they provide * consistent mode setting. */ |
355d95a1c tty_ioctl: drag s... |
669 |
int tty_mode_ioctl(struct tty_struct *tty, struct file *file, |
0fc00e244 [TTY]: Fix networ... |
670 |
unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
671 |
{ |
355d95a1c tty_ioctl: drag s... |
672 |
struct tty_struct *real_tty; |
1da177e4c Linux-2.6.12-rc2 |
673 |
void __user *p = (void __user *)arg; |
8f5200218 tty: Termios lock... |
674 |
int ret = 0; |
26a2e20f4 tty: Untangle ter... |
675 |
struct ktermios kterm; |
1da177e4c Linux-2.6.12-rc2 |
676 |
|
8d075b199 tty: add a helper... |
677 |
BUG_ON(file == NULL); |
1da177e4c Linux-2.6.12-rc2 |
678 679 680 681 682 683 684 685 |
if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) real_tty = tty->link; else real_tty = tty; switch (cmd) { #ifdef TIOCGETP |
355d95a1c tty_ioctl: drag s... |
686 687 688 689 690 |
case TIOCGETP: return get_sgttyb(real_tty, (struct sgttyb __user *) arg); case TIOCSETP: case TIOCSETN: return set_sgttyb(real_tty, (struct sgttyb __user *) arg); |
1da177e4c Linux-2.6.12-rc2 |
691 692 |
#endif #ifdef TIOCGETC |
355d95a1c tty_ioctl: drag s... |
693 694 695 696 |
case TIOCGETC: return get_tchars(real_tty, p); case TIOCSETC: return set_tchars(real_tty, p); |
1da177e4c Linux-2.6.12-rc2 |
697 698 |
#endif #ifdef TIOCGLTC |
355d95a1c tty_ioctl: drag s... |
699 700 701 702 |
case TIOCGLTC: return get_ltchars(real_tty, p); case TIOCSLTC: return set_ltchars(real_tty, p); |
1da177e4c Linux-2.6.12-rc2 |
703 |
#endif |
355d95a1c tty_ioctl: drag s... |
704 705 706 707 708 709 |
case TCSETSF: return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD); case TCSETSW: return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD); case TCSETS: return set_termios(real_tty, p, TERMIOS_OLD); |
edc6afc54 [PATCH] tty: swit... |
710 |
#ifndef TCGETS2 |
355d95a1c tty_ioctl: drag s... |
711 |
case TCGETS: |
26a2e20f4 tty: Untangle ter... |
712 713 |
copy_termios(real_tty, &kterm); if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) |
8f5200218 tty: Termios lock... |
714 |
ret = -EFAULT; |
8f5200218 tty: Termios lock... |
715 |
return ret; |
edc6afc54 [PATCH] tty: swit... |
716 |
#else |
355d95a1c tty_ioctl: drag s... |
717 |
case TCGETS: |
26a2e20f4 tty: Untangle ter... |
718 719 |
copy_termios(real_tty, &kterm); if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) |
8f5200218 tty: Termios lock... |
720 |
ret = -EFAULT; |
8f5200218 tty: Termios lock... |
721 |
return ret; |
355d95a1c tty_ioctl: drag s... |
722 |
case TCGETS2: |
26a2e20f4 tty: Untangle ter... |
723 724 |
copy_termios(real_tty, &kterm); if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm)) |
8f5200218 tty: Termios lock... |
725 |
ret = -EFAULT; |
8f5200218 tty: Termios lock... |
726 |
return ret; |
355d95a1c tty_ioctl: drag s... |
727 728 729 730 731 732 |
case TCSETSF2: return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); case TCSETSW2: return set_termios(real_tty, p, TERMIOS_WAIT); case TCSETS2: return set_termios(real_tty, p, 0); |
edc6afc54 [PATCH] tty: swit... |
733 |
#endif |
355d95a1c tty_ioctl: drag s... |
734 735 736 737 738 739 740 741 |
case TCGETA: return get_termio(real_tty, p); case TCSETAF: return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO); case TCSETAW: return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO); case TCSETA: return set_termios(real_tty, p, TERMIOS_TERMIO); |
0fc00e244 [TTY]: Fix networ... |
742 |
#ifndef TCGETS2 |
355d95a1c tty_ioctl: drag s... |
743 |
case TIOCGLCKTRMIOS: |
26a2e20f4 tty: Untangle ter... |
744 745 |
copy_termios_locked(real_tty, &kterm); if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm)) |
8f5200218 tty: Termios lock... |
746 |
ret = -EFAULT; |
8f5200218 tty: Termios lock... |
747 |
return ret; |
355d95a1c tty_ioctl: drag s... |
748 749 750 |
case TIOCSLCKTRMIOS: if (!capable(CAP_SYS_ADMIN)) return -EPERM; |
26a2e20f4 tty: Untangle ter... |
751 752 |
copy_termios_locked(real_tty, &kterm); if (user_termios_to_kernel_termios(&kterm, |
355d95a1c tty_ioctl: drag s... |
753 |
(struct termios __user *) arg)) |
26a2e20f4 tty: Untangle ter... |
754 |
return -EFAULT; |
6a1c0680c tty: Convert term... |
755 |
down_write(&real_tty->termios_rwsem); |
adc8d746c tty: move the ter... |
756 |
real_tty->termios_locked = kterm; |
6a1c0680c tty: Convert term... |
757 |
up_write(&real_tty->termios_rwsem); |
26a2e20f4 tty: Untangle ter... |
758 |
return 0; |
0fc00e244 [TTY]: Fix networ... |
759 |
#else |
355d95a1c tty_ioctl: drag s... |
760 |
case TIOCGLCKTRMIOS: |
26a2e20f4 tty: Untangle ter... |
761 762 |
copy_termios_locked(real_tty, &kterm); if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm)) |
8f5200218 tty: Termios lock... |
763 |
ret = -EFAULT; |
8f5200218 tty: Termios lock... |
764 |
return ret; |
355d95a1c tty_ioctl: drag s... |
765 766 |
case TIOCSLCKTRMIOS: if (!capable(CAP_SYS_ADMIN)) |
26a2e20f4 tty: Untangle ter... |
767 768 769 |
return -EPERM; copy_termios_locked(real_tty, &kterm); if (user_termios_to_kernel_termios_1(&kterm, |
355d95a1c tty_ioctl: drag s... |
770 |
(struct termios __user *) arg)) |
26a2e20f4 tty: Untangle ter... |
771 |
return -EFAULT; |
6a1c0680c tty: Convert term... |
772 |
down_write(&real_tty->termios_rwsem); |
adc8d746c tty: move the ter... |
773 |
real_tty->termios_locked = kterm; |
6a1c0680c tty: Convert term... |
774 |
up_write(&real_tty->termios_rwsem); |
8f5200218 tty: Termios lock... |
775 |
return ret; |
0fc00e244 [TTY]: Fix networ... |
776 |
#endif |
1d65b4a08 tty: Add termiox |
777 |
#ifdef TCGETX |
5dca607bc tty: fix unused w... |
778 779 |
case TCGETX: { struct termiox ktermx; |
1d65b4a08 tty: Add termiox |
780 781 |
if (real_tty->termiox == NULL) return -EINVAL; |
6a1c0680c tty: Convert term... |
782 |
down_read(&real_tty->termios_rwsem); |
26a2e20f4 tty: Untangle ter... |
783 |
memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox)); |
6a1c0680c tty: Convert term... |
784 |
up_read(&real_tty->termios_rwsem); |
26a2e20f4 tty: Untangle ter... |
785 786 |
if (copy_to_user(p, &ktermx, sizeof(struct termiox))) ret = -EFAULT; |
8f5200218 tty: Termios lock... |
787 |
return ret; |
5dca607bc tty: fix unused w... |
788 |
} |
1d65b4a08 tty: Add termiox |
789 790 791 792 793 794 795 |
case TCSETX: return set_termiox(real_tty, p, 0); case TCSETXW: return set_termiox(real_tty, p, TERMIOS_WAIT); case TCSETXF: return set_termiox(real_tty, p, TERMIOS_FLUSH); #endif |
355d95a1c tty_ioctl: drag s... |
796 |
case TIOCGSOFTCAR: |
26a2e20f4 tty: Untangle ter... |
797 798 |
copy_termios(real_tty, &kterm); ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0, |
355d95a1c tty_ioctl: drag s... |
799 |
(int __user *)arg); |
8f5200218 tty: Termios lock... |
800 |
return ret; |
355d95a1c tty_ioctl: drag s... |
801 802 803 |
case TIOCSSOFTCAR: if (get_user(arg, (unsigned int __user *) arg)) return -EFAULT; |
f753f3272 tty: TIOCGSOFTCAR... |
804 |
return tty_change_softcar(real_tty, arg); |
355d95a1c tty_ioctl: drag s... |
805 806 |
default: return -ENOIOCTLCMD; |
0fc00e244 [TTY]: Fix networ... |
807 808 |
} } |
0fc00e244 [TTY]: Fix networ... |
809 |
EXPORT_SYMBOL_GPL(tty_mode_ioctl); |
e7f3880cd tty: Fix recursiv... |
810 811 812 |
/* Caller guarantees ldisc reference is held */ static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg) |
0fc00e244 [TTY]: Fix networ... |
813 |
{ |
e7f3880cd tty: Fix recursiv... |
814 |
struct tty_ldisc *ld = tty->ldisc; |
0fc00e244 [TTY]: Fix networ... |
815 |
|
0fc00e244 [TTY]: Fix networ... |
816 817 |
switch (arg) { case TCIFLUSH: |
a1bf95844 tty: Add driver u... |
818 |
if (ld && ld->ops->flush_buffer) { |
a352def21 tty: Ldisc revamp |
819 |
ld->ops->flush_buffer(tty); |
a1bf95844 tty: Add driver u... |
820 821 |
tty_unthrottle(tty); } |
0fc00e244 [TTY]: Fix networ... |
822 823 |
break; case TCIOFLUSH: |
a1bf95844 tty: Add driver u... |
824 |
if (ld && ld->ops->flush_buffer) { |
a352def21 tty: Ldisc revamp |
825 |
ld->ops->flush_buffer(tty); |
a1bf95844 tty: Add driver u... |
826 827 |
tty_unthrottle(tty); } |
df561f668 treewide: Use fal... |
828 |
fallthrough; |
0fc00e244 [TTY]: Fix networ... |
829 |
case TCOFLUSH: |
f34d7a5b7 tty: The big oper... |
830 |
tty_driver_flush_buffer(tty); |
0fc00e244 [TTY]: Fix networ... |
831 832 |
break; default: |
0fc00e244 [TTY]: Fix networ... |
833 834 |
return -EINVAL; } |
0fc00e244 [TTY]: Fix networ... |
835 836 |
return 0; } |
e7f3880cd tty: Fix recursiv... |
837 838 839 840 841 842 843 844 845 846 847 848 849 850 |
int tty_perform_flush(struct tty_struct *tty, unsigned long arg) { struct tty_ldisc *ld; int retval = tty_check_change(tty); if (retval) return retval; ld = tty_ldisc_ref_wait(tty); retval = __tty_perform_flush(tty, arg); if (ld) tty_ldisc_deref(ld); return retval; } |
0fc00e244 [TTY]: Fix networ... |
851 |
EXPORT_SYMBOL_GPL(tty_perform_flush); |
47afa7a5a tty: some ICANON ... |
852 |
int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, |
0fc00e244 [TTY]: Fix networ... |
853 854 |
unsigned int cmd, unsigned long arg) { |
0fc00e244 [TTY]: Fix networ... |
855 |
int retval; |
0fc00e244 [TTY]: Fix networ... |
856 |
switch (cmd) { |
355d95a1c tty_ioctl: drag s... |
857 858 859 860 861 862 |
case TCXONC: retval = tty_check_change(tty); if (retval) return retval; switch (arg) { case TCOOFF: |
c545b66c6 tty: Serialize tc... |
863 |
spin_lock_irq(&tty->flow_lock); |
355d95a1c tty_ioctl: drag s... |
864 865 |
if (!tty->flow_stopped) { tty->flow_stopped = 1; |
c545b66c6 tty: Serialize tc... |
866 |
__stop_tty(tty); |
1da177e4c Linux-2.6.12-rc2 |
867 |
} |
c545b66c6 tty: Serialize tc... |
868 |
spin_unlock_irq(&tty->flow_lock); |
355d95a1c tty_ioctl: drag s... |
869 870 |
break; case TCOON: |
c545b66c6 tty: Serialize tc... |
871 |
spin_lock_irq(&tty->flow_lock); |
355d95a1c tty_ioctl: drag s... |
872 873 |
if (tty->flow_stopped) { tty->flow_stopped = 0; |
c545b66c6 tty: Serialize tc... |
874 |
__start_tty(tty); |
355d95a1c tty_ioctl: drag s... |
875 |
} |
c545b66c6 tty: Serialize tc... |
876 |
spin_unlock_irq(&tty->flow_lock); |
355d95a1c tty_ioctl: drag s... |
877 878 879 |
break; case TCIOFF: if (STOP_CHAR(tty) != __DISABLED_CHAR) |
c274f6ef1 tty: Hold termios... |
880 |
retval = tty_send_xchar(tty, STOP_CHAR(tty)); |
355d95a1c tty_ioctl: drag s... |
881 882 883 |
break; case TCION: if (START_CHAR(tty) != __DISABLED_CHAR) |
c274f6ef1 tty: Hold termios... |
884 |
retval = tty_send_xchar(tty, START_CHAR(tty)); |
355d95a1c tty_ioctl: drag s... |
885 |
break; |
1da177e4c Linux-2.6.12-rc2 |
886 |
default: |
355d95a1c tty_ioctl: drag s... |
887 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
888 |
} |
c274f6ef1 tty: Hold termios... |
889 |
return retval; |
355d95a1c tty_ioctl: drag s... |
890 |
case TCFLSH: |
5cec7bf69 tty: Fix SIGTTOU ... |
891 892 893 |
retval = tty_check_change(tty); if (retval) return retval; |
e7f3880cd tty: Fix recursiv... |
894 |
return __tty_perform_flush(tty, arg); |
355d95a1c tty_ioctl: drag s... |
895 896 897 898 |
default: /* Try the mode commands */ return tty_mode_ioctl(tty, file, cmd, arg); } |
1da177e4c Linux-2.6.12-rc2 |
899 |
} |
47afa7a5a tty: some ICANON ... |
900 |
EXPORT_SYMBOL(n_tty_ioctl_helper); |