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.36 2008/07/04 10:13:52 matthias Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 1995, 1998, 2008 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  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: linux_termios.c,v 1.36 2008/07/04 10:13:52 matthias Exp $");
   34 
   35 #if defined(_KERNEL_OPT)
   36 #include "opt_ptm.h"
   37 #endif
   38 
   39 #include <sys/param.h>
   40 #include <sys/proc.h>
   41 #include <sys/systm.h>
   42 #include <sys/file.h>
   43 #include <sys/filedesc.h>
   44 #include <sys/ioctl.h>
   45 #include <sys/mount.h>
   46 #include <sys/termios.h>
   47 #include <sys/kernel.h>
   48 
   49 #include <sys/syscallargs.h>
   50 
   51 #include <compat/linux/common/linux_types.h>
   52 #include <compat/linux/common/linux_ioctl.h>
   53 #include <compat/linux/common/linux_signal.h>
   54 #include <compat/linux/common/linux_util.h>
   55 #include <compat/linux/common/linux_termios.h>
   56 #include <compat/linux/common/linux_ipc.h>
   57 #include <compat/linux/common/linux_sem.h>
   58 
   59 #include <compat/linux/linux_syscallargs.h>
   60 
   61 #ifdef DEBUG_LINUX
   62 #define DPRINTF(a)      uprintf a
   63 #else
   64 #define DPRINTF(a)
   65 #endif
   66 
   67 int
   68 linux_ioctl_termios(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval)
   69 {
   70         /* {
   71                 syscallarg(int) fd;
   72                 syscallarg(u_long) com;
   73                 syscallarg(void *) data;
   74         } */
   75         file_t *fp;
   76         u_long com;
   77         struct linux_termio tmplt;
   78         struct linux_termios tmplts;
   79         struct termios tmpbts;
   80         int idat;
   81         struct sys_ioctl_args ia;
   82         int error;
   83         char tioclinux;
   84         int (*bsdioctl)(file_t *, u_long, void *);
   85 
   86         if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
   87                 return (EBADF);
   88 
   89         if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
   90                 error = EBADF;
   91                 goto out;
   92         }
   93 
   94         bsdioctl = fp->f_ops->fo_ioctl;
   95         com = SCARG(uap, com);
   96         retval[0] = 0;
   97 
   98         switch (com) {
   99         case LINUX_TCGETS:
  100                 error = (*bsdioctl)(fp, TIOCGETA, &tmpbts);
  101                 if (error)
  102                         goto out;
  103                 bsd_termios_to_linux_termios(&tmpbts, &tmplts);
  104                 error = copyout(&tmplts, SCARG(uap, data), sizeof tmplts);
  105                 goto out;
  106         case LINUX_TCSETS:
  107         case LINUX_TCSETSW:
  108         case LINUX_TCSETSF:
  109                 /*
  110                  * First fill in all fields, so that we keep the current
  111                  * values for fields that Linux doesn't know about.
  112                  */
  113                 error = (*bsdioctl)(fp, TIOCGETA, &tmpbts);
  114                 if (error)
  115                         goto out;
  116                 error = copyin(SCARG(uap, data), &tmplts, sizeof tmplts);
  117                 if (error)
  118                         goto out;
  119                 linux_termios_to_bsd_termios(&tmplts, &tmpbts);
  120                 switch (com) {
  121                 case LINUX_TCSETS:
  122                         com = TIOCSETA;
  123                         break;
  124                 case LINUX_TCSETSW:
  125                         com = TIOCSETAW;
  126                         break;
  127                 case LINUX_TCSETSF:
  128                         com = TIOCSETAF;
  129                         break;
  130                 }
  131                 error = (*bsdioctl)(fp, com, &tmpbts);
  132                 goto out;
  133         case LINUX_TCGETA:
  134                 error = (*bsdioctl)(fp, TIOCGETA, &tmpbts);
  135                 if (error)
  136                         goto out;
  137                 bsd_termios_to_linux_termio(&tmpbts, &tmplt);
  138                 error = copyout(&tmplt, SCARG(uap, data), sizeof tmplt);
  139                 goto out;
  140         case LINUX_TCSETA:
  141         case LINUX_TCSETAW:
  142         case LINUX_TCSETAF:
  143                 /*
  144                  * First fill in all fields, so that we keep the current
  145                  * values for fields that Linux doesn't know about.
  146                  */
  147                 error = (*bsdioctl)(fp, TIOCGETA, &tmpbts);
  148                 if (error)
  149                         goto out;
  150                 error = copyin(SCARG(uap, data), &tmplt, sizeof tmplt);
  151                 if (error)
  152                         goto out;
  153                 linux_termio_to_bsd_termios(&tmplt, &tmpbts);
  154                 switch (com) {
  155                 case LINUX_TCSETA:
  156                         com = TIOCSETA;
  157                         break;
  158                 case LINUX_TCSETAW:
  159                         com = TIOCSETAW;
  160                         break;
  161                 case LINUX_TCSETAF:
  162                         com = TIOCSETAF;
  163                         break;
  164                 }
  165                 error = (*bsdioctl)(fp, com, &tmpbts);
  166                 goto out;
  167         case LINUX_TCFLSH:
  168                 switch((u_long)SCARG(uap, data)) {
  169                 case 0:
  170                         idat = FREAD;
  171                         break;
  172                 case 1:
  173                         idat = FWRITE;
  174                         break;
  175                 case 2:
  176                         idat = 0;
  177                         break;
  178                 default:
  179                         error = EINVAL;
  180                         goto out;
  181                 }
  182                 error = (*bsdioctl)(fp, TIOCFLUSH, &idat);
  183                 goto out;
  184         case LINUX_TIOCGETD:
  185                 error = (*bsdioctl)(fp, TIOCGETD, &idat);
  186                 if (error)
  187                         goto out;
  188                 switch (idat) {
  189                 case TTYDISC:
  190                         idat = LINUX_N_TTY;
  191                         break;
  192                 case SLIPDISC:
  193                         idat = LINUX_N_SLIP;
  194                         break;
  195                 case PPPDISC:
  196                         idat = LINUX_N_PPP;
  197                         break;
  198                 case STRIPDISC:
  199                         idat = LINUX_N_STRIP;
  200                         break;
  201                 /*
  202                  * Linux does not have the tablet line discipline.
  203                  */
  204                 case TABLDISC:
  205                 default:
  206                         idat = -1;      /* XXX What should this be? */
  207                         break;
  208                 }
  209                 error = copyout(&idat, SCARG(uap, data), sizeof idat);
  210                 goto out;
  211         case LINUX_TIOCSETD:
  212                 error = copyin(SCARG(uap, data), &idat, sizeof idat);
  213                 if (error)
  214                         goto out;
  215                 switch (idat) {
  216                 case LINUX_N_TTY:
  217                         idat = TTYDISC;
  218                         break;
  219                 case LINUX_N_SLIP:
  220                         idat = SLIPDISC;
  221                         break;
  222                 case LINUX_N_PPP:
  223                         idat = PPPDISC;
  224                         break;
  225                 case LINUX_N_STRIP:
  226                         idat = STRIPDISC;
  227                         break;
  228                 /*
  229                  * We can't handle the mouse line discipline Linux has.
  230                  */
  231                 case LINUX_N_MOUSE:
  232                 case LINUX_N_AX25:
  233                 case LINUX_N_X25:
  234                 case LINUX_N_6PACK:
  235                 default:
  236                         error = EINVAL;
  237                         goto out;
  238                 }
  239                 error = (*bsdioctl)(fp, TIOCSETD, &idat);
  240                 goto out;
  241         case LINUX_TIOCLINUX:
  242                 error = copyin(SCARG(uap, data), &tioclinux, sizeof tioclinux);
  243                 if (error != 0)
  244                         goto out;
  245                 switch (tioclinux) {
  246                 case LINUX_TIOCLINUX_KERNMSG:
  247                         /*
  248                          * XXX needed to not fail for some things. Could
  249                          * try to use TIOCCONS, but the char argument
  250                          * specifies the VT #, not an fd.
  251                          */
  252                         error = 0;
  253                         goto out;
  254                 case LINUX_TIOCLINUX_COPY:
  255                 case LINUX_TIOCLINUX_PASTE:
  256                 case LINUX_TIOCLINUX_UNBLANK:
  257                 case LINUX_TIOCLINUX_LOADLUT:
  258                 case LINUX_TIOCLINUX_READSHIFT:
  259                 case LINUX_TIOCLINUX_READMOUSE:
  260                 case LINUX_TIOCLINUX_VESABLANK:
  261                 case LINUX_TIOCLINUX_CURCONS:   /* could use VT_GETACTIVE */
  262                         error = EINVAL;
  263                         goto out;
  264                 }
  265                 break;
  266         case LINUX_TIOCGWINSZ:
  267                 SCARG(&ia, com) = TIOCGWINSZ;
  268                 break;
  269         case LINUX_TIOCSWINSZ:
  270                 SCARG(&ia, com) = TIOCSWINSZ;
  271                 break;
  272         case LINUX_TIOCGPGRP:
  273                 SCARG(&ia, com) = TIOCGPGRP;
  274                 break;
  275         case LINUX_TIOCSPGRP:
  276                 SCARG(&ia, com) = TIOCSPGRP;
  277                 break;
  278         case LINUX_FIONREAD:
  279                 SCARG(&ia, com) = FIONREAD;
  280                 break;
  281         case LINUX_FIONBIO:
  282                 SCARG(&ia, com) = FIONBIO;
  283                 break;
  284         case LINUX_FIOASYNC:
  285                 SCARG(&ia, com) = FIOASYNC;
  286                 break;
  287         case LINUX_TIOCEXCL:
  288                 SCARG(&ia, com) = TIOCEXCL;
  289                 break;
  290         case LINUX_TIOCNXCL:
  291                 SCARG(&ia, com) = TIOCNXCL;
  292                 break;
  293         case LINUX_TIOCCONS:
  294                 SCARG(&ia, com) = TIOCCONS;
  295                 break;
  296         case LINUX_TIOCNOTTY:
  297                 SCARG(&ia, com) = TIOCNOTTY;
  298                 break;
  299         case LINUX_TCSBRK:
  300                 idat = (u_long)SCARG(uap, data);
  301                 if (idat != 0)
  302                         SCARG(&ia, com) = TIOCDRAIN;
  303                 else {
  304                         if ((error = (*bsdioctl)(fp, TIOCSBRK, NULL)) != 0)
  305                                 goto out;
  306                         error = tsleep(&idat, PZERO | PCATCH, "linux_tcsbrk", hz / 4);
  307                         if (error == EINTR || error == ERESTART) {
  308                                 (void)(*bsdioctl)(fp, TIOCCBRK, NULL);
  309                                 error = EINTR;
  310                         } else
  311                                 error = (*bsdioctl)(fp, TIOCCBRK, NULL);
  312                         goto out;
  313                 }
  314                 break;
  315         case LINUX_TIOCMGET:
  316                 SCARG(&ia, com) = TIOCMGET;
  317                 break;
  318         case LINUX_TIOCMSET:
  319                 SCARG(&ia, com) = TIOCMSET;
  320                 break;
  321         case LINUX_TIOCMBIC:
  322                 SCARG(&ia, com) = TIOCMBIC;
  323                 break;
  324         case LINUX_TIOCMBIS:
  325                 SCARG(&ia, com) = TIOCMBIS;
  326                 break;
  327 #ifdef LINUX_TIOCGPTN
  328         case LINUX_TIOCGPTN:
  329 #ifndef NO_DEV_PTM
  330                 {
  331                         struct ptmget ptm;
  332 
  333                         error = (*bsdioctl)(fp, TIOCPTSNAME, &ptm);
  334                         if (error != 0)
  335                                 goto out;
  336                         error = copyout(&ptm.sfd, SCARG(uap, data),
  337                             sizeof(ptm.sfd));
  338                         goto out;
  339                 }
  340 #endif /* NO_DEV_PTM */
  341 #endif /* LINUX_TIOCGPTN */
  342 #ifdef LINUX_TIOCSPTLCK
  343         case LINUX_TIOCSPTLCK:
  344                         fd_putfile(SCARG(uap, fd));
  345                         error = copyin(SCARG(uap, data), &idat, sizeof(idat));
  346                         if (error)
  347                                 return error;
  348                         DPRINTF(("TIOCSPTLCK %d\n", idat));
  349                         return 0;
  350 #endif
  351         default:
  352                 error = EINVAL;
  353                 goto out;
  354         }
  355 
  356         SCARG(&ia, fd) = SCARG(uap, fd);
  357         SCARG(&ia, data) = SCARG(uap, data);
  358         error = sys_ioctl(curlwp, &ia, retval);
  359 out:
  360         fd_putfile(SCARG(uap, fd));
  361         return error;
  362 }

Cache object: 4c0830e06fd52623e3312f61452fef7d


[ 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.