Root/drivers/tty/tty_ioctl.c

1/*
2 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
3 *
4 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
5 * which can be dynamically activated and de-activated by the line
6 * discipline handling modules (like SLIP).
7 */
8
9#include <linux/types.h>
10#include <linux/termios.h>
11#include <linux/errno.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/major.h>
15#include <linux/tty.h>
16#include <linux/fcntl.h>
17#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/bitops.h>
21#include <linux/mutex.h>
22#include <linux/compat.h>
23
24#include <asm/io.h>
25#include <asm/uaccess.h>
26
27#undef TTY_DEBUG_WAIT_UNTIL_SENT
28
29#undef DEBUG
30
31/*
32 * Internal flag options for termios setting behavior
33 */
34#define TERMIOS_FLUSH 1
35#define TERMIOS_WAIT 2
36#define TERMIOS_TERMIO 4
37#define TERMIOS_OLD 8
38
39
40/**
41 * tty_chars_in_buffer - characters pending
42 * @tty: terminal
43 *
44 * Return the number of bytes of data in the device private
45 * output queue. If no private method is supplied there is assumed
46 * to be no queue on the device.
47 */
48
49int tty_chars_in_buffer(struct tty_struct *tty)
50{
51    if (tty->ops->chars_in_buffer)
52        return tty->ops->chars_in_buffer(tty);
53    else
54        return 0;
55}
56EXPORT_SYMBOL(tty_chars_in_buffer);
57
58/**
59 * tty_write_room - write queue space
60 * @tty: terminal
61 *
62 * Return the number of bytes that can be queued to this device
63 * at the present time. The result should be treated as a guarantee
64 * and the driver cannot offer a value it later shrinks by more than
65 * the number of bytes written. If no method is provided 2K is always
66 * returned and data may be lost as there will be no flow control.
67 */
68 
69int tty_write_room(struct tty_struct *tty)
70{
71    if (tty->ops->write_room)
72        return tty->ops->write_room(tty);
73    return 2048;
74}
75EXPORT_SYMBOL(tty_write_room);
76
77/**
78 * tty_driver_flush_buffer - discard internal buffer
79 * @tty: terminal
80 *
81 * Discard the internal output buffer for this device. If no method
82 * is provided then either the buffer cannot be hardware flushed or
83 * there is no buffer driver side.
84 */
85void tty_driver_flush_buffer(struct tty_struct *tty)
86{
87    if (tty->ops->flush_buffer)
88        tty->ops->flush_buffer(tty);
89}
90EXPORT_SYMBOL(tty_driver_flush_buffer);
91
92/**
93 * tty_throttle - flow control
94 * @tty: terminal
95 *
96 * Indicate that a tty should stop transmitting data down the stack.
97 * Takes the termios mutex to protect against parallel throttle/unthrottle
98 * and also to ensure the driver can consistently reference its own
99 * termios data at this point when implementing software flow control.
100 */
101
102void tty_throttle(struct tty_struct *tty)
103{
104    mutex_lock(&tty->termios_mutex);
105    /* check TTY_THROTTLED first so it indicates our state */
106    if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
107        tty->ops->throttle)
108        tty->ops->throttle(tty);
109    mutex_unlock(&tty->termios_mutex);
110}
111EXPORT_SYMBOL(tty_throttle);
112
113/**
114 * tty_unthrottle - flow control
115 * @tty: terminal
116 *
117 * Indicate that a tty may continue transmitting data down the stack.
118 * Takes the termios mutex to protect against parallel throttle/unthrottle
119 * and also to ensure the driver can consistently reference its own
120 * termios data at this point when implementing software flow control.
121 *
122 * Drivers should however remember that the stack can issue a throttle,
123 * then change flow control method, then unthrottle.
124 */
125
126void tty_unthrottle(struct tty_struct *tty)
127{
128    mutex_lock(&tty->termios_mutex);
129    if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
130        tty->ops->unthrottle)
131        tty->ops->unthrottle(tty);
132    mutex_unlock(&tty->termios_mutex);
133}
134EXPORT_SYMBOL(tty_unthrottle);
135
136/**
137 * tty_wait_until_sent - wait for I/O to finish
138 * @tty: tty we are waiting for
139 * @timeout: how long we will wait
140 *
141 * Wait for characters pending in a tty driver to hit the wire, or
142 * for a timeout to occur (eg due to flow control)
143 *
144 * Locking: none
145 */
146
147void tty_wait_until_sent(struct tty_struct *tty, long timeout)
148{
149#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
150    char buf[64];
151
152    printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
153#endif
154    if (!timeout)
155        timeout = MAX_SCHEDULE_TIMEOUT;
156    if (wait_event_interruptible_timeout(tty->write_wait,
157            !tty_chars_in_buffer(tty), timeout) >= 0) {
158        if (tty->ops->wait_until_sent)
159            tty->ops->wait_until_sent(tty, timeout);
160    }
161}
162EXPORT_SYMBOL(tty_wait_until_sent);
163
164
165/*
166 * Termios Helper Methods
167 */
168
169static void unset_locked_termios(struct ktermios *termios,
170                 struct ktermios *old,
171                 struct ktermios *locked)
172{
173    int i;
174
175#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
176
177    if (!locked) {
178        printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
179        return;
180    }
181
182    NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
183    NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
184    NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
185    NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
186    termios->c_line = locked->c_line ? old->c_line : termios->c_line;
187    for (i = 0; i < NCCS; i++)
188        termios->c_cc[i] = locked->c_cc[i] ?
189            old->c_cc[i] : termios->c_cc[i];
190    /* FIXME: What should we do for i/ospeed */
191}
192
193/*
194 * Routine which returns the baud rate of the tty
195 *
196 * Note that the baud_table needs to be kept in sync with the
197 * include/asm/termbits.h file.
198 */
199static const speed_t baud_table[] = {
200    0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
201    9600, 19200, 38400, 57600, 115200, 230400, 460800,
202#ifdef __sparc__
203    76800, 153600, 307200, 614400, 921600
204#else
205    500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
206    2500000, 3000000, 3500000, 4000000
207#endif
208};
209
210#ifndef __sparc__
211static const tcflag_t baud_bits[] = {
212    B0, B50, B75, B110, B134, B150, B200, B300, B600,
213    B1200, B1800, B2400, B4800, B9600, B19200, B38400,
214    B57600, B115200, B230400, B460800, B500000, B576000,
215    B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
216    B3000000, B3500000, B4000000
217};
218#else
219static const tcflag_t baud_bits[] = {
220    B0, B50, B75, B110, B134, B150, B200, B300, B600,
221    B1200, B1800, B2400, B4800, B9600, B19200, B38400,
222    B57600, B115200, B230400, B460800, B76800, B153600,
223    B307200, B614400, B921600
224};
225#endif
226
227static int n_baud_table = ARRAY_SIZE(baud_table);
228
229/**
230 * tty_termios_baud_rate
231 * @termios: termios structure
232 *
233 * Convert termios baud rate data into a speed. This should be called
234 * with the termios lock held if this termios is a terminal termios
235 * structure. May change the termios data. Device drivers can call this
236 * function but should use ->c_[io]speed directly as they are updated.
237 *
238 * Locking: none
239 */
240
241speed_t tty_termios_baud_rate(struct ktermios *termios)
242{
243    unsigned int cbaud;
244
245    cbaud = termios->c_cflag & CBAUD;
246
247#ifdef BOTHER
248    /* Magic token for arbitrary speed via c_ispeed/c_ospeed */
249    if (cbaud == BOTHER)
250        return termios->c_ospeed;
251#endif
252    if (cbaud & CBAUDEX) {
253        cbaud &= ~CBAUDEX;
254
255        if (cbaud < 1 || cbaud + 15 > n_baud_table)
256            termios->c_cflag &= ~CBAUDEX;
257        else
258            cbaud += 15;
259    }
260    return baud_table[cbaud];
261}
262EXPORT_SYMBOL(tty_termios_baud_rate);
263
264/**
265 * tty_termios_input_baud_rate
266 * @termios: termios structure
267 *
268 * Convert termios baud rate data into a speed. This should be called
269 * with the termios lock held if this termios is a terminal termios
270 * structure. May change the termios data. Device drivers can call this
271 * function but should use ->c_[io]speed directly as they are updated.
272 *
273 * Locking: none
274 */
275
276speed_t tty_termios_input_baud_rate(struct ktermios *termios)
277{
278#ifdef IBSHIFT
279    unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
280
281    if (cbaud == B0)
282        return tty_termios_baud_rate(termios);
283
284    /* Magic token for arbitrary speed via c_ispeed*/
285    if (cbaud == BOTHER)
286        return termios->c_ispeed;
287
288    if (cbaud & CBAUDEX) {
289        cbaud &= ~CBAUDEX;
290
291        if (cbaud < 1 || cbaud + 15 > n_baud_table)
292            termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
293        else
294            cbaud += 15;
295    }
296    return baud_table[cbaud];
297#else
298    return tty_termios_baud_rate(termios);
299#endif
300}
301EXPORT_SYMBOL(tty_termios_input_baud_rate);
302
303/**
304 * tty_termios_encode_baud_rate
305 * @termios: ktermios structure holding user requested state
306 * @ispeed: input speed
307 * @ospeed: output speed
308 *
309 * Encode the speeds set into the passed termios structure. This is
310 * used as a library helper for drivers so that they can report back
311 * the actual speed selected when it differs from the speed requested
312 *
313 * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
314 * we need to carefully set the bits when the user does not get the
315 * desired speed. We allow small margins and preserve as much of possible
316 * of the input intent to keep compatibility.
317 *
318 * Locking: Caller should hold termios lock. This is already held
319 * when calling this function from the driver termios handler.
320 *
321 * The ifdefs deal with platforms whose owners have yet to update them
322 * and will all go away once this is done.
323 */
324
325void tty_termios_encode_baud_rate(struct ktermios *termios,
326                  speed_t ibaud, speed_t obaud)
327{
328    int i = 0;
329    int ifound = -1, ofound = -1;
330    int iclose = ibaud/50, oclose = obaud/50;
331    int ibinput = 0;
332
333    if (obaud == 0) /* CD dropped */
334        ibaud = 0; /* Clear ibaud to be sure */
335
336    termios->c_ispeed = ibaud;
337    termios->c_ospeed = obaud;
338
339#ifdef BOTHER
340    /* If the user asked for a precise weird speed give a precise weird
341       answer. If they asked for a Bfoo speed they many have problems
342       digesting non-exact replies so fuzz a bit */
343
344    if ((termios->c_cflag & CBAUD) == BOTHER)
345        oclose = 0;
346    if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
347        iclose = 0;
348    if ((termios->c_cflag >> IBSHIFT) & CBAUD)
349        ibinput = 1; /* An input speed was specified */
350#endif
351    termios->c_cflag &= ~CBAUD;
352
353    /*
354     * Our goal is to find a close match to the standard baud rate
355     * returned. Walk the baud rate table and if we get a very close
356     * match then report back the speed as a POSIX Bxxxx value by
357     * preference
358     */
359
360    do {
361        if (obaud - oclose <= baud_table[i] &&
362            obaud + oclose >= baud_table[i]) {
363            termios->c_cflag |= baud_bits[i];
364            ofound = i;
365        }
366        if (ibaud - iclose <= baud_table[i] &&
367            ibaud + iclose >= baud_table[i]) {
368            /* For the case input == output don't set IBAUD bits
369               if the user didn't do so */
370            if (ofound == i && !ibinput)
371                ifound = i;
372#ifdef IBSHIFT
373            else {
374                ifound = i;
375                termios->c_cflag |= (baud_bits[i] << IBSHIFT);
376            }
377#endif
378        }
379    } while (++i < n_baud_table);
380
381    /*
382     * If we found no match then use BOTHER if provided or warn
383     * the user their platform maintainer needs to wake up if not.
384     */
385#ifdef BOTHER
386    if (ofound == -1)
387        termios->c_cflag |= BOTHER;
388    /* Set exact input bits only if the input and output differ or the
389       user already did */
390    if (ifound == -1 && (ibaud != obaud || ibinput))
391        termios->c_cflag |= (BOTHER << IBSHIFT);
392#else
393    if (ifound == -1 || ofound == -1) {
394        printk_once(KERN_WARNING "tty: Unable to return correct "
395              "speed data as your architecture needs updating.\n");
396    }
397#endif
398}
399EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
400
401/**
402 * tty_encode_baud_rate - set baud rate of the tty
403 * @ibaud: input baud rate
404 * @obad: output baud rate
405 *
406 * Update the current termios data for the tty with the new speed
407 * settings. The caller must hold the termios_mutex for the tty in
408 * question.
409 */
410
411void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
412{
413    tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
414}
415EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
416
417/**
418 * tty_get_baud_rate - get tty bit rates
419 * @tty: tty to query
420 *
421 * Returns the baud rate as an integer for this terminal. The
422 * termios lock must be held by the caller and the terminal bit
423 * flags may be updated.
424 *
425 * Locking: none
426 */
427
428speed_t tty_get_baud_rate(struct tty_struct *tty)
429{
430    speed_t baud = tty_termios_baud_rate(tty->termios);
431
432    if (baud == 38400 && tty->alt_speed) {
433        if (!tty->warned) {
434            printk(KERN_WARNING "Use of setserial/setrocket to "
435                        "set SPD_* flags is deprecated\n");
436            tty->warned = 1;
437        }
438        baud = tty->alt_speed;
439    }
440
441    return baud;
442}
443EXPORT_SYMBOL(tty_get_baud_rate);
444
445/**
446 * tty_termios_copy_hw - copy hardware settings
447 * @new: New termios
448 * @old: Old termios
449 *
450 * Propagate the hardware specific terminal setting bits from
451 * the old termios structure to the new one. This is used in cases
452 * where the hardware does not support reconfiguration or as a helper
453 * in some cases where only minimal reconfiguration is supported
454 */
455
456void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
457{
458    /* The bits a dumb device handles in software. Smart devices need
459       to always provide a set_termios method */
460    new->c_cflag &= HUPCL | CREAD | CLOCAL;
461    new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
462    new->c_ispeed = old->c_ispeed;
463    new->c_ospeed = old->c_ospeed;
464}
465EXPORT_SYMBOL(tty_termios_copy_hw);
466
467/**
468 * tty_termios_hw_change - check for setting change
469 * @a: termios
470 * @b: termios to compare
471 *
472 * Check if any of the bits that affect a dumb device have changed
473 * between the two termios structures, or a speed change is needed.
474 */
475
476int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
477{
478    if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
479        return 1;
480    if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
481        return 1;
482    return 0;
483}
484EXPORT_SYMBOL(tty_termios_hw_change);
485
486/**
487 * tty_set_termios - update termios values
488 * @tty: tty to update
489 * @new_termios: desired new value
490 *
491 * Perform updates to the termios values set on this terminal. There
492 * is a bit of layering violation here with n_tty in terms of the
493 * internal knowledge of this function.
494 *
495 * Locking: termios_mutex
496 */
497
498int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
499{
500    struct ktermios old_termios;
501    struct tty_ldisc *ld;
502    unsigned long flags;
503
504    /*
505     * Perform the actual termios internal changes under lock.
506     */
507
508
509    /* FIXME: we need to decide on some locking/ordering semantics
510       for the set_termios notification eventually */
511    mutex_lock(&tty->termios_mutex);
512    old_termios = *tty->termios;
513    *tty->termios = *new_termios;
514    unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
515
516    /* See if packet mode change of state. */
517    if (tty->link && tty->link->packet) {
518        int extproc = (old_termios.c_lflag & EXTPROC) |
519                (tty->termios->c_lflag & EXTPROC);
520        int old_flow = ((old_termios.c_iflag & IXON) &&
521                (old_termios.c_cc[VSTOP] == '\023') &&
522                (old_termios.c_cc[VSTART] == '\021'));
523        int new_flow = (I_IXON(tty) &&
524                STOP_CHAR(tty) == '\023' &&
525                START_CHAR(tty) == '\021');
526        if ((old_flow != new_flow) || extproc) {
527            spin_lock_irqsave(&tty->ctrl_lock, flags);
528            if (old_flow != new_flow) {
529                tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
530                if (new_flow)
531                    tty->ctrl_status |= TIOCPKT_DOSTOP;
532                else
533                    tty->ctrl_status |= TIOCPKT_NOSTOP;
534            }
535            if (extproc)
536                tty->ctrl_status |= TIOCPKT_IOCTL;
537            spin_unlock_irqrestore(&tty->ctrl_lock, flags);
538            wake_up_interruptible(&tty->link->read_wait);
539        }
540    }
541
542    if (tty->ops->set_termios)
543        (*tty->ops->set_termios)(tty, &old_termios);
544    else
545        tty_termios_copy_hw(tty->termios, &old_termios);
546
547    ld = tty_ldisc_ref(tty);
548    if (ld != NULL) {
549        if (ld->ops->set_termios)
550            (ld->ops->set_termios)(tty, &old_termios);
551        tty_ldisc_deref(ld);
552    }
553    mutex_unlock(&tty->termios_mutex);
554    return 0;
555}
556EXPORT_SYMBOL_GPL(tty_set_termios);
557
558/**
559 * set_termios - set termios values for a tty
560 * @tty: terminal device
561 * @arg: user data
562 * @opt: option information
563 *
564 * Helper function to prepare termios data and run necessary other
565 * functions before using tty_set_termios to do the actual changes.
566 *
567 * Locking:
568 * Called functions take ldisc and termios_mutex locks
569 */
570
571static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
572{
573    struct ktermios tmp_termios;
574    struct tty_ldisc *ld;
575    int retval = tty_check_change(tty);
576
577    if (retval)
578        return retval;
579
580    mutex_lock(&tty->termios_mutex);
581    memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
582    mutex_unlock(&tty->termios_mutex);
583
584    if (opt & TERMIOS_TERMIO) {
585        if (user_termio_to_kernel_termios(&tmp_termios,
586                        (struct termio __user *)arg))
587            return -EFAULT;
588#ifdef TCGETS2
589    } else if (opt & TERMIOS_OLD) {
590        if (user_termios_to_kernel_termios_1(&tmp_termios,
591                        (struct termios __user *)arg))
592            return -EFAULT;
593    } else {
594        if (user_termios_to_kernel_termios(&tmp_termios,
595                        (struct termios2 __user *)arg))
596            return -EFAULT;
597    }
598#else
599    } else if (user_termios_to_kernel_termios(&tmp_termios,
600                    (struct termios __user *)arg))
601        return -EFAULT;
602#endif
603
604    /* If old style Bfoo values are used then load c_ispeed/c_ospeed
605     * with the real speed so its unconditionally usable */
606    tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
607    tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
608
609    ld = tty_ldisc_ref(tty);
610
611    if (ld != NULL) {
612        if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
613            ld->ops->flush_buffer(tty);
614        tty_ldisc_deref(ld);
615    }
616
617    if (opt & TERMIOS_WAIT) {
618        tty_wait_until_sent(tty, 0);
619        if (signal_pending(current))
620            return -EINTR;
621    }
622
623    tty_set_termios(tty, &tmp_termios);
624
625    /* FIXME: Arguably if tmp_termios == tty->termios AND the
626       actual requested termios was not tmp_termios then we may
627       want to return an error as no user requested change has
628       succeeded */
629    return 0;
630}
631
632static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
633{
634    mutex_lock(&tty->termios_mutex);
635    memcpy(kterm, tty->termios, sizeof(struct ktermios));
636    mutex_unlock(&tty->termios_mutex);
637}
638
639static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
640{
641    mutex_lock(&tty->termios_mutex);
642    memcpy(kterm, tty->termios_locked, sizeof(struct ktermios));
643    mutex_unlock(&tty->termios_mutex);
644}
645
646static int get_termio(struct tty_struct *tty, struct termio __user *termio)
647{
648    struct ktermios kterm;
649    copy_termios(tty, &kterm);
650    if (kernel_termios_to_user_termio(termio, &kterm))
651        return -EFAULT;
652    return 0;
653}
654
655
656#ifdef TCGETX
657
658/**
659 * set_termiox - set termiox fields if possible
660 * @tty: terminal
661 * @arg: termiox structure from user
662 * @opt: option flags for ioctl type
663 *
664 * Implement the device calling points for the SYS5 termiox ioctl
665 * interface in Linux
666 */
667
668static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
669{
670    struct termiox tnew;
671    struct tty_ldisc *ld;
672
673    if (tty->termiox == NULL)
674        return -EINVAL;
675    if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
676        return -EFAULT;
677
678    ld = tty_ldisc_ref(tty);
679    if (ld != NULL) {
680        if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
681            ld->ops->flush_buffer(tty);
682        tty_ldisc_deref(ld);
683    }
684    if (opt & TERMIOS_WAIT) {
685        tty_wait_until_sent(tty, 0);
686        if (signal_pending(current))
687            return -EINTR;
688    }
689
690    mutex_lock(&tty->termios_mutex);
691    if (tty->ops->set_termiox)
692        tty->ops->set_termiox(tty, &tnew);
693    mutex_unlock(&tty->termios_mutex);
694    return 0;
695}
696
697#endif
698
699
700#ifdef TIOCGETP
701/*
702 * These are deprecated, but there is limited support..
703 *
704 * The "sg_flags" translation is a joke..
705 */
706static int get_sgflags(struct tty_struct *tty)
707{
708    int flags = 0;
709
710    if (!(tty->termios->c_lflag & ICANON)) {
711        if (tty->termios->c_lflag & ISIG)
712            flags |= 0x02; /* cbreak */
713        else
714            flags |= 0x20; /* raw */
715    }
716    if (tty->termios->c_lflag & ECHO)
717        flags |= 0x08; /* echo */
718    if (tty->termios->c_oflag & OPOST)
719        if (tty->termios->c_oflag & ONLCR)
720            flags |= 0x10; /* crmod */
721    return flags;
722}
723
724static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
725{
726    struct sgttyb tmp;
727
728    mutex_lock(&tty->termios_mutex);
729    tmp.sg_ispeed = tty->termios->c_ispeed;
730    tmp.sg_ospeed = tty->termios->c_ospeed;
731    tmp.sg_erase = tty->termios->c_cc[VERASE];
732    tmp.sg_kill = tty->termios->c_cc[VKILL];
733    tmp.sg_flags = get_sgflags(tty);
734    mutex_unlock(&tty->termios_mutex);
735
736    return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
737}
738
739static void set_sgflags(struct ktermios *termios, int flags)
740{
741    termios->c_iflag = ICRNL | IXON;
742    termios->c_oflag = 0;
743    termios->c_lflag = ISIG | ICANON;
744    if (flags & 0x02) { /* cbreak */
745        termios->c_iflag = 0;
746        termios->c_lflag &= ~ICANON;
747    }
748    if (flags & 0x08) { /* echo */
749        termios->c_lflag |= ECHO | ECHOE | ECHOK |
750                    ECHOCTL | ECHOKE | IEXTEN;
751    }
752    if (flags & 0x10) { /* crmod */
753        termios->c_oflag |= OPOST | ONLCR;
754    }
755    if (flags & 0x20) { /* raw */
756        termios->c_iflag = 0;
757        termios->c_lflag &= ~(ISIG | ICANON);
758    }
759    if (!(termios->c_lflag & ICANON)) {
760        termios->c_cc[VMIN] = 1;
761        termios->c_cc[VTIME] = 0;
762    }
763}
764
765/**
766 * set_sgttyb - set legacy terminal values
767 * @tty: tty structure
768 * @sgttyb: pointer to old style terminal structure
769 *
770 * Updates a terminal from the legacy BSD style terminal information
771 * structure.
772 *
773 * Locking: termios_mutex
774 */
775
776static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
777{
778    int retval;
779    struct sgttyb tmp;
780    struct ktermios termios;
781
782    retval = tty_check_change(tty);
783    if (retval)
784        return retval;
785
786    if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
787        return -EFAULT;
788
789    mutex_lock(&tty->termios_mutex);
790    termios = *tty->termios;
791    termios.c_cc[VERASE] = tmp.sg_erase;
792    termios.c_cc[VKILL] = tmp.sg_kill;
793    set_sgflags(&termios, tmp.sg_flags);
794    /* Try and encode into Bfoo format */
795#ifdef BOTHER
796    tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
797                        termios.c_ospeed);
798#endif
799    mutex_unlock(&tty->termios_mutex);
800    tty_set_termios(tty, &termios);
801    return 0;
802}
803#endif
804
805#ifdef TIOCGETC
806static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
807{
808    struct tchars tmp;
809
810    mutex_lock(&tty->termios_mutex);
811    tmp.t_intrc = tty->termios->c_cc[VINTR];
812    tmp.t_quitc = tty->termios->c_cc[VQUIT];
813    tmp.t_startc = tty->termios->c_cc[VSTART];
814    tmp.t_stopc = tty->termios->c_cc[VSTOP];
815    tmp.t_eofc = tty->termios->c_cc[VEOF];
816    tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
817    mutex_unlock(&tty->termios_mutex);
818    return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
819}
820
821static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
822{
823    struct tchars tmp;
824
825    if (copy_from_user(&tmp, tchars, sizeof(tmp)))
826        return -EFAULT;
827    mutex_lock(&tty->termios_mutex);
828    tty->termios->c_cc[VINTR] = tmp.t_intrc;
829    tty->termios->c_cc[VQUIT] = tmp.t_quitc;
830    tty->termios->c_cc[VSTART] = tmp.t_startc;
831    tty->termios->c_cc[VSTOP] = tmp.t_stopc;
832    tty->termios->c_cc[VEOF] = tmp.t_eofc;
833    tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
834    mutex_unlock(&tty->termios_mutex);
835    return 0;
836}
837#endif
838
839#ifdef TIOCGLTC
840static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
841{
842    struct ltchars tmp;
843
844    mutex_lock(&tty->termios_mutex);
845    tmp.t_suspc = tty->termios->c_cc[VSUSP];
846    /* what is dsuspc anyway? */
847    tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
848    tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
849    /* what is flushc anyway? */
850    tmp.t_flushc = tty->termios->c_cc[VEOL2];
851    tmp.t_werasc = tty->termios->c_cc[VWERASE];
852    tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
853    mutex_unlock(&tty->termios_mutex);
854    return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
855}
856
857static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
858{
859    struct ltchars tmp;
860
861    if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
862        return -EFAULT;
863
864    mutex_lock(&tty->termios_mutex);
865    tty->termios->c_cc[VSUSP] = tmp.t_suspc;
866    /* what is dsuspc anyway? */
867    tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
868    tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
869    /* what is flushc anyway? */
870    tty->termios->c_cc[VEOL2] = tmp.t_flushc;
871    tty->termios->c_cc[VWERASE] = tmp.t_werasc;
872    tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
873    mutex_unlock(&tty->termios_mutex);
874    return 0;
875}
876#endif
877
878/**
879 * send_prio_char - send priority character
880 *
881 * Send a high priority character to the tty even if stopped
882 *
883 * Locking: none for xchar method, write ordering for write method.
884 */
885
886static int send_prio_char(struct tty_struct *tty, char ch)
887{
888    int was_stopped = tty->stopped;
889
890    if (tty->ops->send_xchar) {
891        tty->ops->send_xchar(tty, ch);
892        return 0;
893    }
894
895    if (tty_write_lock(tty, 0) < 0)
896        return -ERESTARTSYS;
897
898    if (was_stopped)
899        start_tty(tty);
900    tty->ops->write(tty, &ch, 1);
901    if (was_stopped)
902        stop_tty(tty);
903    tty_write_unlock(tty);
904    return 0;
905}
906
907/**
908 * tty_change_softcar - carrier change ioctl helper
909 * @tty: tty to update
910 * @arg: enable/disable CLOCAL
911 *
912 * Perform a change to the CLOCAL state and call into the driver
913 * layer to make it visible. All done with the termios mutex
914 */
915
916static int tty_change_softcar(struct tty_struct *tty, int arg)
917{
918    int ret = 0;
919    int bit = arg ? CLOCAL : 0;
920    struct ktermios old;
921
922    mutex_lock(&tty->termios_mutex);
923    old = *tty->termios;
924    tty->termios->c_cflag &= ~CLOCAL;
925    tty->termios->c_cflag |= bit;
926    if (tty->ops->set_termios)
927        tty->ops->set_termios(tty, &old);
928    if ((tty->termios->c_cflag & CLOCAL) != bit)
929        ret = -EINVAL;
930    mutex_unlock(&tty->termios_mutex);
931    return ret;
932}
933
934/**
935 * tty_mode_ioctl - mode related ioctls
936 * @tty: tty for the ioctl
937 * @file: file pointer for the tty
938 * @cmd: command
939 * @arg: ioctl argument
940 *
941 * Perform non line discipline specific mode control ioctls. This
942 * is designed to be called by line disciplines to ensure they provide
943 * consistent mode setting.
944 */
945
946int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
947            unsigned int cmd, unsigned long arg)
948{
949    struct tty_struct *real_tty;
950    void __user *p = (void __user *)arg;
951    int ret = 0;
952    struct ktermios kterm;
953
954    BUG_ON(file == NULL);
955
956    if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
957        tty->driver->subtype == PTY_TYPE_MASTER)
958        real_tty = tty->link;
959    else
960        real_tty = tty;
961
962    switch (cmd) {
963#ifdef TIOCGETP
964    case TIOCGETP:
965        return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
966    case TIOCSETP:
967    case TIOCSETN:
968        return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
969#endif
970#ifdef TIOCGETC
971    case TIOCGETC:
972        return get_tchars(real_tty, p);
973    case TIOCSETC:
974        return set_tchars(real_tty, p);
975#endif
976#ifdef TIOCGLTC
977    case TIOCGLTC:
978        return get_ltchars(real_tty, p);
979    case TIOCSLTC:
980        return set_ltchars(real_tty, p);
981#endif
982    case TCSETSF:
983        return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
984    case TCSETSW:
985        return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
986    case TCSETS:
987        return set_termios(real_tty, p, TERMIOS_OLD);
988#ifndef TCGETS2
989    case TCGETS:
990        copy_termios(real_tty, &kterm);
991        if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
992            ret = -EFAULT;
993        return ret;
994#else
995    case TCGETS:
996        copy_termios(real_tty, &kterm);
997        if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
998            ret = -EFAULT;
999        return ret;
1000    case TCGETS2:
1001        copy_termios(real_tty, &kterm);
1002        if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
1003            ret = -EFAULT;
1004        return ret;
1005    case TCSETSF2:
1006        return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
1007    case TCSETSW2:
1008        return set_termios(real_tty, p, TERMIOS_WAIT);
1009    case TCSETS2:
1010        return set_termios(real_tty, p, 0);
1011#endif
1012    case TCGETA:
1013        return get_termio(real_tty, p);
1014    case TCSETAF:
1015        return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
1016    case TCSETAW:
1017        return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
1018    case TCSETA:
1019        return set_termios(real_tty, p, TERMIOS_TERMIO);
1020#ifndef TCGETS2
1021    case TIOCGLCKTRMIOS:
1022        copy_termios_locked(real_tty, &kterm);
1023        if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
1024            ret = -EFAULT;
1025        return ret;
1026    case TIOCSLCKTRMIOS:
1027        if (!capable(CAP_SYS_ADMIN))
1028            return -EPERM;
1029        copy_termios_locked(real_tty, &kterm);
1030        if (user_termios_to_kernel_termios(&kterm,
1031                           (struct termios __user *) arg))
1032            return -EFAULT;
1033        mutex_lock(&real_tty->termios_mutex);
1034        memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1035        mutex_unlock(&real_tty->termios_mutex);
1036        return 0;
1037#else
1038    case TIOCGLCKTRMIOS:
1039        copy_termios_locked(real_tty, &kterm);
1040        if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
1041            ret = -EFAULT;
1042        return ret;
1043    case TIOCSLCKTRMIOS:
1044        if (!capable(CAP_SYS_ADMIN))
1045            return -EPERM;
1046        copy_termios_locked(real_tty, &kterm);
1047        if (user_termios_to_kernel_termios_1(&kterm,
1048                           (struct termios __user *) arg))
1049            return -EFAULT;
1050        mutex_lock(&real_tty->termios_mutex);
1051        memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1052        mutex_unlock(&real_tty->termios_mutex);
1053        return ret;
1054#endif
1055#ifdef TCGETX
1056    case TCGETX: {
1057        struct termiox ktermx;
1058        if (real_tty->termiox == NULL)
1059            return -EINVAL;
1060        mutex_lock(&real_tty->termios_mutex);
1061        memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
1062        mutex_unlock(&real_tty->termios_mutex);
1063        if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
1064            ret = -EFAULT;
1065        return ret;
1066    }
1067    case TCSETX:
1068        return set_termiox(real_tty, p, 0);
1069    case TCSETXW:
1070        return set_termiox(real_tty, p, TERMIOS_WAIT);
1071    case TCSETXF:
1072        return set_termiox(real_tty, p, TERMIOS_FLUSH);
1073#endif
1074    case TIOCGSOFTCAR:
1075        copy_termios(real_tty, &kterm);
1076        ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
1077                        (int __user *)arg);
1078        return ret;
1079    case TIOCSSOFTCAR:
1080        if (get_user(arg, (unsigned int __user *) arg))
1081            return -EFAULT;
1082        return tty_change_softcar(real_tty, arg);
1083    default:
1084        return -ENOIOCTLCMD;
1085    }
1086}
1087EXPORT_SYMBOL_GPL(tty_mode_ioctl);
1088
1089int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1090{
1091    struct tty_ldisc *ld;
1092    int retval = tty_check_change(tty);
1093    if (retval)
1094        return retval;
1095
1096    ld = tty_ldisc_ref_wait(tty);
1097    switch (arg) {
1098    case TCIFLUSH:
1099        if (ld && ld->ops->flush_buffer)
1100            ld->ops->flush_buffer(tty);
1101        break;
1102    case TCIOFLUSH:
1103        if (ld && ld->ops->flush_buffer)
1104            ld->ops->flush_buffer(tty);
1105        /* fall through */
1106    case TCOFLUSH:
1107        tty_driver_flush_buffer(tty);
1108        break;
1109    default:
1110        tty_ldisc_deref(ld);
1111        return -EINVAL;
1112    }
1113    tty_ldisc_deref(ld);
1114    return 0;
1115}
1116EXPORT_SYMBOL_GPL(tty_perform_flush);
1117
1118int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
1119               unsigned int cmd, unsigned long arg)
1120{
1121    unsigned long flags;
1122    int retval;
1123
1124    switch (cmd) {
1125    case TCXONC:
1126        retval = tty_check_change(tty);
1127        if (retval)
1128            return retval;
1129        switch (arg) {
1130        case TCOOFF:
1131            if (!tty->flow_stopped) {
1132                tty->flow_stopped = 1;
1133                stop_tty(tty);
1134            }
1135            break;
1136        case TCOON:
1137            if (tty->flow_stopped) {
1138                tty->flow_stopped = 0;
1139                start_tty(tty);
1140            }
1141            break;
1142        case TCIOFF:
1143            if (STOP_CHAR(tty) != __DISABLED_CHAR)
1144                return send_prio_char(tty, STOP_CHAR(tty));
1145            break;
1146        case TCION:
1147            if (START_CHAR(tty) != __DISABLED_CHAR)
1148                return send_prio_char(tty, START_CHAR(tty));
1149            break;
1150        default:
1151            return -EINVAL;
1152        }
1153        return 0;
1154    case TCFLSH:
1155        return tty_perform_flush(tty, arg);
1156    case TIOCPKT:
1157    {
1158        int pktmode;
1159
1160        if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
1161            tty->driver->subtype != PTY_TYPE_MASTER)
1162            return -ENOTTY;
1163        if (get_user(pktmode, (int __user *) arg))
1164            return -EFAULT;
1165        spin_lock_irqsave(&tty->ctrl_lock, flags);
1166        if (pktmode) {
1167            if (!tty->packet) {
1168                tty->packet = 1;
1169                tty->link->ctrl_status = 0;
1170            }
1171        } else
1172            tty->packet = 0;
1173        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1174        return 0;
1175    }
1176    default:
1177        /* Try the mode commands */
1178        return tty_mode_ioctl(tty, file, cmd, arg);
1179    }
1180}
1181EXPORT_SYMBOL(n_tty_ioctl_helper);
1182
1183#ifdef CONFIG_COMPAT
1184long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file,
1185                    unsigned int cmd, unsigned long arg)
1186{
1187    switch (cmd) {
1188    case TIOCGLCKTRMIOS:
1189    case TIOCSLCKTRMIOS:
1190        return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg));
1191    default:
1192        return -ENOIOCTLCMD;
1193    }
1194}
1195EXPORT_SYMBOL(n_tty_compat_ioctl_helper);
1196#endif
1197
1198

Archive Download this file



interactive