The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/linux/common/linux_termios.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: linux_termios.c,v 1.22.2.1 2007/01/11 20:31:48 bouyer Exp $    */
    2 
    3 /*-
    4  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Frank van der Linden and Eric Haszlakiewicz.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: linux_termios.c,v 1.22.2.1 2007/01/11 20:31:48 bouyer Exp $");
   41 
   42 #if defined(_KERNEL_OPT)
   43 #include "opt_ptm.h"
   44 #endif
   45 
   46 #include <sys/param.h>
   47 #include <sys/proc.h>
   48 #include <sys/systm.h>
   49 #include <sys/file.h>
   50 #include <sys/filedesc.h>
   51 #include <sys/ioctl.h>
   52 #include <sys/mount.h>
   53 #include <sys/termios.h>
   54 
   55 #include <sys/sa.h>
   56 #include <sys/syscallargs.h>
   57 
   58 #include <compat/linux/common/linux_types.h>
   59 #include <compat/linux/common/linux_ioctl.h>
   60 #include <compat/linux/common/linux_signal.h>
   61 #include <compat/linux/common/linux_util.h>
   62 #include <compat/linux/common/linux_termios.h>
   63 
   64 #include <compat/linux/linux_syscallargs.h>
   65 
   66 static speed_t linux_speeds[] = {
   67         0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
   68         9600, 19200, 38400, 57600, 115200, 230400
   69 };
   70 
   71 static const int linux_spmasks[] = {
   72         LINUX_B0, LINUX_B50, LINUX_B75, LINUX_B110, LINUX_B134, LINUX_B150,
   73         LINUX_B200, LINUX_B300, LINUX_B600, LINUX_B1200, LINUX_B1800,
   74         LINUX_B2400, LINUX_B4800, LINUX_B9600, LINUX_B19200, LINUX_B38400,
   75         LINUX_B57600, LINUX_B115200, LINUX_B230400
   76 };
   77 
   78 
   79 static void linux_termio_to_bsd_termios __P((struct linux_termio *,
   80                                              struct termios *));
   81 static void bsd_termios_to_linux_termio __P((struct termios *,
   82                                              struct linux_termio *));
   83 static void linux_termios_to_bsd_termios __P((struct linux_termios *,
   84                                               struct termios *));
   85 static void bsd_termios_to_linux_termios __P((struct termios *,
   86                                               struct linux_termios *));
   87 
   88 /*
   89  * Deal with termio ioctl cruft. This doesn't look very good..
   90  * XXX too much code duplication, obviously..
   91  *
   92  * The conversion routines between Linux and BSD structures assume
   93  * that the fields are already filled with the current values,
   94  * so that fields present in BSD but not in Linux keep their current
   95  * values.
   96  */
   97 
   98 static void
   99 linux_termio_to_bsd_termios(lt, bts)
  100         struct linux_termio *lt;
  101         struct termios *bts;
  102 {
  103         int index;
  104 
  105         bts->c_iflag = 0;
  106         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNBRK, IGNBRK);
  107         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_BRKINT, BRKINT);
  108         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNPAR, IGNPAR);
  109         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INPCK, INPCK);
  110         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ISTRIP, ISTRIP);
  111         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INLCR, INLCR);
  112         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNCR, IGNCR);
  113         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ICRNL, ICRNL);
  114         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXON, IXON);
  115         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXANY, IXANY);
  116         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXOFF, IXOFF);
  117         bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IMAXBEL, IMAXBEL);
  118 
  119         bts->c_oflag = 0;
  120         bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_OPOST, OPOST);
  121         bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_ONLCR, ONLCR);
  122         bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_XTABS, OXTABS);
  123 
  124         /*
  125          * This could have been:
  126          * bts->c_cflag = (lt->c_flag & LINUX_CSIZE) << 4
  127          * But who knows, those values might perhaps change one day.
  128          */
  129         switch (lt->c_cflag & LINUX_CSIZE) {
  130         case LINUX_CS5:
  131                 bts->c_cflag = CS5;
  132                 break;
  133         case LINUX_CS6:
  134                 bts->c_cflag = CS6;
  135                 break;
  136         case LINUX_CS7:
  137                 bts->c_cflag = CS7;
  138                 break;
  139         case LINUX_CS8:
  140                 bts->c_cflag = CS8;
  141                 break;
  142         }
  143         bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CSTOPB, CSTOPB);
  144         bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CREAD, CREAD);
  145         bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARENB, PARENB);
  146         bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARODD, PARODD);
  147         bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_HUPCL, HUPCL);
  148         bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CLOCAL, CLOCAL);
  149         bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CRTSCTS, CRTSCTS);
  150 
  151         bts->c_lflag = 0;
  152         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ISIG, ISIG);
  153         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ICANON, ICANON);
  154         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHO, ECHO);
  155         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOE, ECHOE);
  156         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOK, ECHOK);
  157         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHONL, ECHONL);
  158         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_NOFLSH, NOFLSH);
  159         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_TOSTOP, TOSTOP);
  160         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOCTL, ECHOCTL);
  161         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOPRT, ECHOPRT);
  162         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOKE, ECHOKE);
  163         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_FLUSHO, FLUSHO);
  164         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_PENDIN, PENDIN);
  165         bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_IEXTEN, IEXTEN);
  166 
  167         index = lt->c_cflag & LINUX_CBAUD;
  168         if (index & LINUX_CBAUDEX)
  169                 index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
  170         bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
  171 
  172         bts->c_cc[VINTR] = lt->c_cc[LINUX_OLD_VINTR];
  173         bts->c_cc[VQUIT] = lt->c_cc[LINUX_OLD_VQUIT];
  174         bts->c_cc[VERASE] = lt->c_cc[LINUX_OLD_VERASE];
  175         bts->c_cc[VKILL] = lt->c_cc[LINUX_OLD_VKILL];
  176         bts->c_cc[VEOF] = lt->c_cc[LINUX_OLD_VEOF];
  177         bts->c_cc[VTIME] = lt->c_cc[LINUX_OLD_VTIME];
  178         bts->c_cc[VMIN] = lt->c_cc[LINUX_OLD_VMIN];
  179 }
  180 
  181 static void
  182 bsd_termios_to_linux_termio(bts, lt)
  183         struct termios *bts;
  184         struct linux_termio *lt;
  185 {
  186         int i, mask;
  187 
  188         lt->c_iflag = 0;
  189         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
  190         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
  191         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
  192         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
  193         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
  194         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
  195         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
  196         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
  197         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
  198         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
  199         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
  200         lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
  201 
  202         lt->c_oflag = 0;
  203         lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
  204         lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
  205         lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
  206 
  207         switch (bts->c_cflag & CSIZE) {
  208         case CS5:
  209                 lt->c_cflag = LINUX_CS5;
  210                 break;
  211         case CS6:
  212                 lt->c_cflag = LINUX_CS6;
  213                 break;
  214         case CS7:
  215                 lt->c_cflag = LINUX_CS7;
  216                 break;
  217         case CS8:
  218                 lt->c_cflag = LINUX_CS8;
  219                 break;
  220         }
  221         lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
  222         lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
  223         lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
  224         lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
  225         lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
  226         lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
  227         lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
  228 
  229         lt->c_lflag = 0;
  230         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
  231         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
  232         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
  233         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
  234         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
  235         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
  236         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
  237         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
  238         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
  239         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
  240         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
  241         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
  242         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
  243         lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
  244 
  245         mask = LINUX_B9600;     /* XXX default value should this be 0? */
  246         for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
  247                 if (bts->c_ospeed == linux_speeds[i]) {
  248                         mask = linux_spmasks[i];
  249                         break;
  250                 }
  251         }
  252         lt->c_cflag |= mask;
  253 
  254         lt->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
  255         lt->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
  256         lt->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
  257         lt->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
  258         lt->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
  259         lt->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
  260         lt->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
  261         lt->c_cc[LINUX_VSWTC] = 0;
  262 
  263         /* XXX should be fixed someday */
  264         lt->c_line = 0;
  265 }
  266 
  267 static void
  268 linux_termios_to_bsd_termios(lts, bts)
  269         struct linux_termios *lts;
  270         struct termios *bts;
  271 {
  272         int index;
  273 
  274         bts->c_iflag = 0;
  275         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNBRK, IGNBRK);
  276         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_BRKINT, BRKINT);
  277         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNPAR, IGNPAR);
  278         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INPCK, INPCK);
  279         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ISTRIP, ISTRIP);
  280         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INLCR, INLCR);
  281         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNCR, IGNCR);
  282         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ICRNL, ICRNL);
  283         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXON, IXON);
  284         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXANY, IXANY);
  285         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXOFF, IXOFF);
  286         bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IMAXBEL, IMAXBEL);
  287 
  288         bts->c_oflag = 0;
  289         bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_OPOST, OPOST);
  290         bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_ONLCR, ONLCR);
  291         bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_XTABS, OXTABS);
  292 
  293         bts->c_cflag = 0;
  294         switch (lts->c_cflag & LINUX_CSIZE) {
  295         case LINUX_CS5:
  296                 bts->c_cflag = CS5;
  297                 break;
  298         case LINUX_CS6:
  299                 bts->c_cflag = CS6;
  300                 break;
  301         case LINUX_CS7:
  302                 bts->c_cflag = CS7;
  303                 break;
  304         case LINUX_CS8:
  305                 bts->c_cflag = CS8;
  306                 break;
  307         }
  308         bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CSTOPB, CSTOPB);
  309         bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CREAD, CREAD);
  310         bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARENB, PARENB);
  311         bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARODD, PARODD);
  312         bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_HUPCL, HUPCL);
  313         bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CLOCAL, CLOCAL);
  314         bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CRTSCTS, CRTSCTS);
  315 
  316         bts->c_lflag = 0;
  317         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ISIG, ISIG);
  318         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ICANON, ICANON);
  319         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHO, ECHO);
  320         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOE, ECHOE);
  321         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOK, ECHOK);
  322         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHONL, ECHONL);
  323         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_NOFLSH, NOFLSH);
  324         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_TOSTOP, TOSTOP);
  325         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOCTL, ECHOCTL);
  326         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOPRT, ECHOPRT);
  327         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOKE, ECHOKE);
  328         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_FLUSHO, FLUSHO);
  329         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_PENDIN, PENDIN);
  330         bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_IEXTEN, IEXTEN);
  331 
  332         index = lts->c_cflag & LINUX_CBAUD;
  333         if (index & LINUX_CBAUDEX)
  334                 index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
  335         bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
  336         /*
  337          * A null c_ospeed causes NetBSD to hangup the terminal.
  338          * Linux does not do this, and it sets c_ospeed to zero
  339          * sometimes. If it is null, we store -1 in the kernel
  340          */
  341         if (bts->c_ospeed == 0)
  342                 bts->c_ospeed = -1;
  343 
  344         bts->c_cc[VINTR] = lts->c_cc[LINUX_VINTR];
  345         bts->c_cc[VQUIT] = lts->c_cc[LINUX_VQUIT];
  346         bts->c_cc[VERASE] = lts->c_cc[LINUX_VERASE];
  347         bts->c_cc[VKILL] = lts->c_cc[LINUX_VKILL];
  348         bts->c_cc[VEOF] = lts->c_cc[LINUX_VEOF];
  349         bts->c_cc[VTIME] = lts->c_cc[LINUX_VTIME];
  350         bts->c_cc[VMIN] = lts->c_cc[LINUX_VMIN];
  351         bts->c_cc[VEOL] = lts->c_cc[LINUX_VEOL];
  352         bts->c_cc[VEOL2] = lts->c_cc[LINUX_VEOL2];
  353         bts->c_cc[VWERASE] = lts->c_cc[LINUX_VWERASE];
  354         bts->c_cc[VSUSP] = lts->c_cc[LINUX_VSUSP];
  355         bts->c_cc[VSTART] = lts->c_cc[LINUX_VSTART];
  356         bts->c_cc[VSTOP] = lts->c_cc[LINUX_VSTOP];
  357         bts->c_cc[VLNEXT] = lts->c_cc[LINUX_VLNEXT];
  358         bts->c_cc[VDISCARD] = lts->c_cc[LINUX_VDISCARD];
  359         bts->c_cc[VREPRINT] = lts->c_cc[LINUX_VREPRINT];
  360 }
  361 
  362 static void
  363 bsd_termios_to_linux_termios(bts, lts)
  364         struct termios *bts;
  365         struct linux_termios *lts;
  366 {
  367         int i, mask;
  368 
  369         lts->c_iflag = 0;
  370         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
  371         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
  372         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
  373         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
  374         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
  375         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
  376         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
  377         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
  378         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
  379         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
  380         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
  381         lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
  382 
  383         lts->c_oflag = 0;
  384         lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
  385         lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
  386         lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
  387 
  388         switch (bts->c_cflag & CSIZE) {
  389         case CS5:
  390                 lts->c_cflag = LINUX_CS5;
  391                 break;
  392         case CS6:
  393                 lts->c_cflag = LINUX_CS6;
  394                 break;
  395         case CS7:
  396                 lts->c_cflag = LINUX_CS7;
  397                 break;
  398         case CS8:
  399                 lts->c_cflag = LINUX_CS8;
  400                 break;
  401         }
  402         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS5, LINUX_CS5);
  403         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS6, LINUX_CS6);
  404         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS7, LINUX_CS7);
  405         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS8, LINUX_CS8);
  406         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
  407         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
  408         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
  409         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
  410         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
  411         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
  412         lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
  413 
  414         lts->c_lflag = 0;
  415         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
  416         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
  417         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
  418         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
  419         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
  420         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
  421         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
  422         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
  423         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
  424         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
  425         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
  426         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
  427         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
  428         lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
  429 
  430         mask = LINUX_B9600;     /* XXX default value */
  431         for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
  432                 if (bts->c_ospeed == linux_speeds[i]) {
  433                         mask = linux_spmasks[i];
  434                         break;
  435                 }
  436         }
  437         /*
  438          * A null c_ospeed causes NetBSD to hangup the terminal.
  439          * Linux does not do this, and it sets c_ospeed to zero
  440          * sometimes. If it is null, we store -1 in the kernel
  441          */
  442         if (bts->c_ospeed == -1)
  443                 bts->c_ospeed = 0;
  444         lts->c_cflag |= mask;
  445 
  446         lts->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
  447         lts->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
  448         lts->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
  449         lts->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
  450         lts->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
  451         lts->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
  452         lts->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
  453         lts->c_cc[LINUX_VEOL] = bts->c_cc[VEOL];
  454         lts->c_cc[LINUX_VEOL2] = bts->c_cc[VEOL2];
  455         lts->c_cc[LINUX_VWERASE] = bts->c_cc[VWERASE];
  456         lts->c_cc[LINUX_VSUSP] = bts->c_cc[VSUSP];
  457         lts->c_cc[LINUX_VSTART] = bts->c_cc[VSTART];
  458         lts->c_cc[LINUX_VSTOP] = bts->c_cc[VSTOP];
  459         lts->c_cc[LINUX_VLNEXT] = bts->c_cc[VLNEXT];
  460         lts->c_cc[LINUX_VDISCARD] = bts->c_cc[VDISCARD];
  461         lts->c_cc[LINUX_VREPRINT] = bts->c_cc[VREPRINT];
  462         lts->c_cc[LINUX_VSWTC] = 0;
  463 
  464         /* XXX should be fixed someday */
  465         lts->c_line = 0;
  466 }
  467 
  468 int
  469 linux_ioctl_termios(p, uap, retval)
  470         struct proc *p;
  471         struct linux_sys_ioctl_args /* {
  472                 syscallarg(int) fd;
  473                 syscallarg(u_long) com;
  474                 syscallarg(caddr_t) data;
  475         } */ *uap;
  476         register_t *retval;
  477 {
  478         struct file *fp;
  479         struct filedesc *fdp;
  480         u_long com;
  481         struct linux_termio tmplt;
  482         struct linux_termios tmplts;
  483         struct termios tmpbts;
  484         int idat;
  485         struct sys_ioctl_args ia;
  486         int error;
  487         char tioclinux;
  488         int (*bsdioctl)(struct file *, u_long, void *, struct proc *);
  489 
  490         fdp = p->p_fd;
  491         if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
  492                 return (EBADF);
  493 
  494         if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
  495                 error = EBADF;
  496                 goto out;
  497         }
  498 
  499         FILE_USE(fp);
  500 
  501         bsdioctl = fp->f_ops->fo_ioctl;
  502         com = SCARG(uap, com);
  503         retval[0] = 0;
  504 
  505         switch (com & 0xffff) {
  506         case LINUX_TCGETS:
  507                 error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
  508                 if (error)
  509                         goto out;
  510                 bsd_termios_to_linux_termios(&tmpbts, &tmplts);
  511                 error = copyout(&tmplts, SCARG(uap, data), sizeof tmplts);
  512                 goto out;
  513         case LINUX_TCSETS:
  514         case LINUX_TCSETSW:
  515         case LINUX_TCSETSF:
  516                 /*
  517                  * First fill in all fields, so that we keep the current
  518                  * values for fields that Linux doesn't know about.
  519                  */
  520                 error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
  521                 if (error)
  522                         goto out;
  523                 error = copyin(SCARG(uap, data), &tmplts, sizeof tmplts);
  524                 if (error)
  525                         goto out;
  526                 linux_termios_to_bsd_termios(&tmplts, &tmpbts);
  527                 switch (com) {
  528                 case LINUX_TCSETS:
  529                         com = TIOCSETA;
  530                         break;
  531                 case LINUX_TCSETSW:
  532                         com = TIOCSETAW;
  533                         break;
  534                 case LINUX_TCSETSF:
  535                         com = TIOCSETAF;
  536                         break;
  537                 }
  538                 error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, p);
  539                 goto out;
  540         case LINUX_TCGETA:
  541                 error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
  542                 if (error)
  543                         goto out;
  544                 bsd_termios_to_linux_termio(&tmpbts, &tmplt);
  545                 error = copyout(&tmplt, SCARG(uap, data), sizeof tmplt);
  546                 goto out;
  547         case LINUX_TCSETA:
  548         case LINUX_TCSETAW:
  549         case LINUX_TCSETAF:
  550                 /*
  551                  * First fill in all fields, so that we keep the current
  552                  * values for fields that Linux doesn't know about.
  553                  */
  554                 error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
  555                 if (error)
  556                         goto out;
  557                 error = copyin(SCARG(uap, data), &tmplt, sizeof tmplt);
  558                 if (error)
  559                         goto out;
  560                 linux_termio_to_bsd_termios(&tmplt, &tmpbts);
  561                 switch (com) {
  562                 case LINUX_TCSETA:
  563                         com = TIOCSETA;
  564                         break;
  565                 case LINUX_TCSETAW:
  566                         com = TIOCSETAW;
  567                         break;
  568                 case LINUX_TCSETAF:
  569                         com = TIOCSETAF;
  570                         break;
  571                 }
  572                 error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, p);
  573                 goto out;
  574         case LINUX_TCFLSH:
  575                 switch((u_long)SCARG(uap, data)) {
  576                 case 0:
  577                         idat = FREAD;
  578                         break;
  579                 case 1:
  580                         idat = FWRITE;
  581                         break;
  582                 case 2:
  583                         idat = 0;
  584                         break;
  585                 default:
  586                         error = EINVAL;
  587                         goto out;
  588                 }
  589                 error = (*bsdioctl)(fp, TIOCFLUSH, (caddr_t)&idat, p);
  590                 goto out;
  591         case LINUX_TIOCGETD:
  592                 error = (*bsdioctl)(fp, TIOCGETD, (caddr_t)&idat, p);
  593                 if (error)
  594                         goto out;
  595                 switch (idat) {
  596                 case TTYDISC:
  597                         idat = LINUX_N_TTY;
  598                         break;
  599                 case SLIPDISC:
  600                         idat = LINUX_N_SLIP;
  601                         break;
  602                 case PPPDISC:
  603                         idat = LINUX_N_PPP;
  604                         break;
  605                 case STRIPDISC:
  606                         idat = LINUX_N_STRIP;
  607                         break;
  608                 /*
  609                  * Linux does not have the tablet line discipline.
  610                  */
  611                 case TABLDISC:
  612                 default:
  613                         idat = -1;      /* XXX What should this be? */
  614                         break;
  615                 }
  616                 error = copyout(&idat, SCARG(uap, data), sizeof idat);
  617                 goto out;
  618         case LINUX_TIOCSETD:
  619                 error = copyin(SCARG(uap, data), &idat, sizeof idat);
  620                 if (error)
  621                         goto out;
  622                 switch (idat) {
  623                 case LINUX_N_TTY:
  624                         idat = TTYDISC;
  625                         break;
  626                 case LINUX_N_SLIP:
  627                         idat = SLIPDISC;
  628                         break;
  629                 case LINUX_N_PPP:
  630                         idat = PPPDISC;
  631                         break;
  632                 case LINUX_N_STRIP:
  633                         idat = STRIPDISC;
  634                         break;
  635                 /*
  636                  * We can't handle the mouse line discipline Linux has.
  637                  */
  638                 case LINUX_N_MOUSE:
  639                 case LINUX_N_AX25:
  640                 case LINUX_N_X25:
  641                 case LINUX_N_6PACK:
  642                 default:
  643                         error = EINVAL;
  644                         goto out;
  645                 }
  646                 error = (*bsdioctl)(fp, TIOCSETD, (caddr_t)&idat, p);
  647                 goto out;
  648         case LINUX_TIOCLINUX:
  649                 error = copyin(SCARG(uap, data), &tioclinux, sizeof tioclinux);
  650                 if (error != 0)
  651                         goto out;
  652                 switch (tioclinux) {
  653                 case LINUX_TIOCLINUX_KERNMSG:
  654                         /*
  655                          * XXX needed to not fail for some things. Could
  656                          * try to use TIOCCONS, but the char argument
  657                          * specifies the VT #, not an fd.
  658                          */
  659                         error = 0;
  660                         goto out;
  661                 case LINUX_TIOCLINUX_COPY:
  662                 case LINUX_TIOCLINUX_PASTE:
  663                 case LINUX_TIOCLINUX_UNBLANK:
  664                 case LINUX_TIOCLINUX_LOADLUT:
  665                 case LINUX_TIOCLINUX_READSHIFT:
  666                 case LINUX_TIOCLINUX_READMOUSE:
  667                 case LINUX_TIOCLINUX_VESABLANK:
  668                 case LINUX_TIOCLINUX_CURCONS:   /* could use VT_GETACTIVE */
  669                         error = EINVAL;
  670                         goto out;
  671                 }
  672                 break;
  673         case LINUX_TIOCGWINSZ:
  674                 SCARG(&ia, com) = TIOCGWINSZ;
  675                 break;
  676         case LINUX_TIOCSWINSZ:
  677                 SCARG(&ia, com) = TIOCSWINSZ;
  678                 break;
  679         case LINUX_TIOCGPGRP:
  680                 SCARG(&ia, com) = TIOCGPGRP;
  681                 break;
  682         case LINUX_TIOCSPGRP:
  683                 SCARG(&ia, com) = TIOCSPGRP;
  684                 break;
  685         case LINUX_FIONREAD:
  686                 SCARG(&ia, com) = FIONREAD;
  687                 break;
  688         case LINUX_FIONBIO:
  689                 SCARG(&ia, com) = FIONBIO;
  690                 break;
  691         case LINUX_FIOASYNC:
  692                 SCARG(&ia, com) = FIOASYNC;
  693                 break;
  694         case LINUX_TIOCEXCL:
  695                 SCARG(&ia, com) = TIOCEXCL;
  696                 break;
  697         case LINUX_TIOCNXCL:
  698                 SCARG(&ia, com) = TIOCNXCL;
  699                 break;
  700         case LINUX_TIOCCONS:
  701                 SCARG(&ia, com) = TIOCCONS;
  702                 break;
  703         case LINUX_TIOCNOTTY:
  704                 SCARG(&ia, com) = TIOCNOTTY;
  705                 break;
  706         case LINUX_TCSBRK:
  707                 SCARG(&ia, com) = SCARG(uap, data) ? TIOCDRAIN : TIOCSBRK;
  708                 break;
  709         case LINUX_TIOCMGET:
  710                 SCARG(&ia, com) = TIOCMGET;
  711                 break;
  712         case LINUX_TIOCMSET:
  713                 SCARG(&ia, com) = TIOCMSET;
  714                 break;
  715         case LINUX_TIOCMBIC:
  716                 SCARG(&ia, com) = TIOCMBIC;
  717                 break;
  718         case LINUX_TIOCMBIS:
  719                 SCARG(&ia, com) = TIOCMBIS;
  720                 break;
  721 #ifdef LINUX_TIOCGPTN
  722         case LINUX_TIOCGPTN:
  723 #ifndef NO_DEV_PTM
  724                 {
  725                         caddr_t sg = stackgap_init(p, 0);
  726                         struct ptmget ptm, *ptmp = stackgap_alloc(p, &sg,
  727                                 sizeof(*ptmp));
  728 
  729                         SCARG(&ia, fd) = SCARG(uap, fd);
  730                         SCARG(&ia, com) = TIOCPTSNAME;
  731                         SCARG(&ia, data) = ptmp;
  732 
  733                         if ((error = sys_ioctl(curlwp, &ia, retval)) != 0)
  734                                 goto out;
  735 
  736                         if ((error = copyin(ptmp, &ptm, sizeof(ptm))) != 0)
  737                                 printf("copyin %d\n", error);
  738 
  739                         error = copyout(&ptm.sfd, SCARG(uap, data),
  740                             sizeof(ptm.sfd));
  741                         goto out;
  742                 }
  743 #endif /* NO_DEV_PTM */
  744 #endif /* LINUX_TIOCGPTN */
  745         default:
  746                 error = EINVAL;
  747                 goto out;
  748         }
  749 
  750         SCARG(&ia, fd) = SCARG(uap, fd);
  751         SCARG(&ia, data) = SCARG(uap, data);
  752         /* XXX NJWLWP */
  753         error = sys_ioctl(curlwp, &ia, retval);
  754 out:
  755         FILE_UNUSE(fp, p);
  756         return error;
  757 }

Cache object: 85bcee5729b58a6ed740c68c7742d997


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.