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/sunos32/sunos32_ioctl.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: sunos32_ioctl.c,v 1.29 2008/05/29 14:51:26 mrg Exp $   */
    2 /* from: NetBSD: sunos_ioctl.c,v 1.35 2001/02/03 22:20:02 mrg Exp       */
    3 
    4 /*
    5  * Copyright (c) 2001 Matthew R. Green
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 /*
   31  * Copyright (c) 1993 Markus Wild.
   32  * All rights reserved.
   33  *
   34  * Redistribution and use in source and binary forms, with or without
   35  * modification, are permitted provided that the following conditions
   36  * are met:
   37  * 1. Redistributions of source code must retain the above copyright
   38  *    notice, this list of conditions and the following disclaimer.
   39  * 2. The name of the author may not be used to endorse or promote products
   40  *    derived from this software without specific prior written permission
   41  *
   42  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   43  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   44  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   45  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   46  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   47  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   48  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   49  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   50  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   51  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   52  *
   53  * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
   54  */
   55 
   56 #include <sys/cdefs.h>
   57 __KERNEL_RCSID(0, "$NetBSD: sunos32_ioctl.c,v 1.29 2008/05/29 14:51:26 mrg Exp $");
   58 
   59 #if defined(_KERNEL_OPT)
   60 #include "opt_compat_netbsd32.h"
   61 #include "opt_execfmt.h"
   62 #endif
   63 
   64 #include <sys/param.h>
   65 #include <sys/proc.h>
   66 #include <sys/systm.h>
   67 #include <sys/file.h>
   68 #include <sys/filedesc.h>
   69 #include <sys/ioctl.h>
   70 #include <sys/termios.h>
   71 #include <sys/tty.h>
   72 #include <sys/socket.h>
   73 #include <sys/audioio.h>
   74 #include <sys/vnode.h>
   75 #include <sys/mount.h>
   76 #include <sys/disklabel.h>
   77 #include <sys/syscallargs.h>
   78 
   79 #include <miscfs/specfs/specdev.h>
   80 
   81 #include <net/if.h>
   82 
   83 #include <dev/sun/disklabel.h>
   84 
   85 #include <compat/sys/sockio.h>
   86 
   87 #include <compat/sunos/sunos.h>
   88 #include <compat/sunos/sunos_syscallargs.h>
   89 #include <compat/netbsd32/netbsd32.h>
   90 #include <compat/netbsd32/netbsd32_syscallargs.h>
   91 #include <compat/sunos32/sunos32.h>
   92 #include <compat/sunos32/sunos32_syscallargs.h>
   93 #include <compat/common/compat_util.h>
   94 
   95 /*
   96  * SunOS ioctl calls.
   97  * This file is something of a hodge-podge.
   98  * Support gets added as things turn up....
   99  */
  100 
  101 static const struct speedtab sptab[] = {
  102         { 0, 0 },
  103         { 50, 1 },
  104         { 75, 2 },
  105         { 110, 3 },
  106         { 134, 4 },
  107         { 135, 4 },
  108         { 150, 5 },
  109         { 200, 6 },
  110         { 300, 7 },
  111         { 600, 8 },
  112         { 1200, 9 },
  113         { 1800, 10 },
  114         { 2400, 11 },
  115         { 4800, 12 },
  116         { 9600, 13 },
  117         { 19200, 14 },
  118         { 38400, 15 },
  119         { -1, -1 }
  120 };
  121 
  122 static const netbsd32_u_long s2btab[] = {
  123         0,
  124         50,
  125         75,
  126         110,
  127         134,
  128         150,
  129         200,
  130         300,
  131         600,
  132         1200,
  133         1800,
  134         2400,
  135         4800,
  136         9600,
  137         19200,
  138         38400,
  139 };
  140 
  141 static void stios2btios(struct sunos_termios *, struct termios *);
  142 static void btios2stios(struct termios *, struct sunos_termios *);
  143 static void stios2stio(struct sunos_termios *, struct sunos_termio *);
  144 static void stio2stios(struct sunos_termio *, struct sunos_termios *);
  145 
  146 /*
  147  * These two conversion functions have mostly been done
  148  * with some perl cut&paste, then hand-edited to comment
  149  * out what doesn't exist under NetBSD.
  150  * A note from Markus's code:
  151  *      (l & BITMASK1) / BITMASK1 * BITMASK2  is translated
  152  *      optimally by gcc m68k, much better than any ?: stuff.
  153  *      Code may vary with different architectures of course.
  154  *
  155  * I don't know what optimizer you used, but seeing divu's and
  156  * bfextu's in the m68k assembly output did not encourage me...
  157  * as well, gcc on the sparc definitely generates much better
  158  * code with `?:'.
  159  */
  160 
  161 static void
  162 stios2btios(struct sunos_termios *st, struct termios *bt)
  163 {
  164         netbsd32_u_long l, r;
  165 
  166         l = st->c_iflag;
  167         r =     ((l & 0x00000001) ? IGNBRK      : 0);
  168         r |=    ((l & 0x00000002) ? BRKINT      : 0);
  169         r |=    ((l & 0x00000004) ? IGNPAR      : 0);
  170         r |=    ((l & 0x00000008) ? PARMRK      : 0);
  171         r |=    ((l & 0x00000010) ? INPCK       : 0);
  172         r |=    ((l & 0x00000020) ? ISTRIP      : 0);
  173         r |=    ((l & 0x00000040) ? INLCR       : 0);
  174         r |=    ((l & 0x00000080) ? IGNCR       : 0);
  175         r |=    ((l & 0x00000100) ? ICRNL       : 0);
  176         /*      ((l & 0x00000200) ? IUCLC       : 0) */
  177         r |=    ((l & 0x00000400) ? IXON        : 0);
  178         r |=    ((l & 0x00000800) ? IXANY       : 0);
  179         r |=    ((l & 0x00001000) ? IXOFF       : 0);
  180         r |=    ((l & 0x00002000) ? IMAXBEL     : 0);
  181         bt->c_iflag = r;
  182 
  183         l = st->c_oflag;
  184         r =     ((l & 0x00000001) ? OPOST       : 0);
  185         /*      ((l & 0x00000002) ? OLCUC       : 0) */
  186         r |=    ((l & 0x00000004) ? ONLCR       : 0);
  187         /*      ((l & 0x00000008) ? OCRNL       : 0) */
  188         /*      ((l & 0x00000010) ? ONOCR       : 0) */
  189         /*      ((l & 0x00000020) ? ONLRET      : 0) */
  190         /*      ((l & 0x00000040) ? OFILL       : 0) */
  191         /*      ((l & 0x00000080) ? OFDEL       : 0) */
  192         /*      ((l & 0x00000100) ? NLDLY       : 0) */
  193         /*      ((l & 0x00000100) ? NL1         : 0) */
  194         /*      ((l & 0x00000600) ? CRDLY       : 0) */
  195         /*      ((l & 0x00000200) ? CR1         : 0) */
  196         /*      ((l & 0x00000400) ? CR2         : 0) */
  197         /*      ((l & 0x00000600) ? CR3         : 0) */
  198         /*      ((l & 0x00001800) ? TABDLY      : 0) */
  199         /*      ((l & 0x00000800) ? TAB1        : 0) */
  200         /*      ((l & 0x00001000) ? TAB2        : 0) */
  201         r |=    ((l & 0x00001800) ? OXTABS      : 0);
  202         /*      ((l & 0x00002000) ? BSDLY       : 0) */
  203         /*      ((l & 0x00002000) ? BS1         : 0) */
  204         /*      ((l & 0x00004000) ? VTDLY       : 0) */
  205         /*      ((l & 0x00004000) ? VT1         : 0) */
  206         /*      ((l & 0x00008000) ? FFDLY       : 0) */
  207         /*      ((l & 0x00008000) ? FF1         : 0) */
  208         /*      ((l & 0x00010000) ? PAGEOUT     : 0) */
  209         /*      ((l & 0x00020000) ? WRAP        : 0) */
  210         bt->c_oflag = r;
  211 
  212         l = st->c_cflag;
  213         switch (l & 0x00000030) {
  214         case 0:
  215                 r = CS5;
  216                 break;
  217         case 0x00000010:
  218                 r = CS6;
  219                 break;
  220         case 0x00000020:
  221                 r = CS7;
  222                 break;
  223         case 0x00000030:
  224                 r = CS8;
  225                 break;
  226         }
  227         r |=    ((l & 0x00000040) ? CSTOPB      : 0);
  228         r |=    ((l & 0x00000080) ? CREAD       : 0);
  229         r |=    ((l & 0x00000100) ? PARENB      : 0);
  230         r |=    ((l & 0x00000200) ? PARODD      : 0);
  231         r |=    ((l & 0x00000400) ? HUPCL       : 0);
  232         r |=    ((l & 0x00000800) ? CLOCAL      : 0);
  233         /*      ((l & 0x00001000) ? LOBLK       : 0) */
  234         r |=    ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
  235         bt->c_cflag = r;
  236 
  237         bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
  238 
  239         l = st->c_lflag;
  240         r =     ((l & 0x00000001) ? ISIG        : 0);
  241         r |=    ((l & 0x00000002) ? ICANON      : 0);
  242         /*      ((l & 0x00000004) ? XCASE       : 0) */
  243         r |=    ((l & 0x00000008) ? ECHO        : 0);
  244         r |=    ((l & 0x00000010) ? ECHOE       : 0);
  245         r |=    ((l & 0x00000020) ? ECHOK       : 0);
  246         r |=    ((l & 0x00000040) ? ECHONL      : 0);
  247         r |=    ((l & 0x00000080) ? NOFLSH      : 0);
  248         r |=    ((l & 0x00000100) ? TOSTOP      : 0);
  249         r |=    ((l & 0x00000200) ? ECHOCTL     : 0);
  250         r |=    ((l & 0x00000400) ? ECHOPRT     : 0);
  251         r |=    ((l & 0x00000800) ? ECHOKE      : 0);
  252         /*      ((l & 0x00001000) ? DEFECHO     : 0) */
  253         r |=    ((l & 0x00002000) ? FLUSHO      : 0);
  254         r |=    ((l & 0x00004000) ? PENDIN      : 0);
  255         bt->c_lflag = r;
  256 
  257         bt->c_cc[VINTR]    = st->c_cc[0]  ? st->c_cc[0]  : _POSIX_VDISABLE;
  258         bt->c_cc[VQUIT]    = st->c_cc[1]  ? st->c_cc[1]  : _POSIX_VDISABLE;
  259         bt->c_cc[VERASE]   = st->c_cc[2]  ? st->c_cc[2]  : _POSIX_VDISABLE;
  260         bt->c_cc[VKILL]    = st->c_cc[3]  ? st->c_cc[3]  : _POSIX_VDISABLE;
  261         bt->c_cc[VEOF]     = st->c_cc[4]  ? st->c_cc[4]  : _POSIX_VDISABLE;
  262         bt->c_cc[VEOL]     = st->c_cc[5]  ? st->c_cc[5]  : _POSIX_VDISABLE;
  263         bt->c_cc[VEOL2]    = st->c_cc[6]  ? st->c_cc[6]  : _POSIX_VDISABLE;
  264     /*  bt->c_cc[VSWTCH]   = st->c_cc[7]  ? st->c_cc[7]  : _POSIX_VDISABLE; */
  265         bt->c_cc[VSTART]   = st->c_cc[8]  ? st->c_cc[8]  : _POSIX_VDISABLE;
  266         bt->c_cc[VSTOP]    = st->c_cc[9]  ? st->c_cc[9]  : _POSIX_VDISABLE;
  267         bt->c_cc[VSUSP]    = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
  268         bt->c_cc[VDSUSP]   = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
  269         bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
  270         bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
  271         bt->c_cc[VWERASE]  = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
  272         bt->c_cc[VLNEXT]   = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
  273         bt->c_cc[VSTATUS]  = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
  274 
  275         /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
  276         bt->c_cc[VMIN]     = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
  277         bt->c_cc[VTIME]    = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
  278 }
  279 
  280 
  281 static void
  282 btios2stios(struct termios *bt, struct sunos_termios *st)
  283 {
  284         netbsd32_u_long l, r;
  285         int s;
  286 
  287         l = bt->c_iflag;
  288         r =     ((l &  IGNBRK) ? 0x00000001     : 0);
  289         r |=    ((l &  BRKINT) ? 0x00000002     : 0);
  290         r |=    ((l &  IGNPAR) ? 0x00000004     : 0);
  291         r |=    ((l &  PARMRK) ? 0x00000008     : 0);
  292         r |=    ((l &   INPCK) ? 0x00000010     : 0);
  293         r |=    ((l &  ISTRIP) ? 0x00000020     : 0);
  294         r |=    ((l &   INLCR) ? 0x00000040     : 0);
  295         r |=    ((l &   IGNCR) ? 0x00000080     : 0);
  296         r |=    ((l &   ICRNL) ? 0x00000100     : 0);
  297         /*      ((l &   IUCLC) ? 0x00000200     : 0) */
  298         r |=    ((l &    IXON) ? 0x00000400     : 0);
  299         r |=    ((l &   IXANY) ? 0x00000800     : 0);
  300         r |=    ((l &   IXOFF) ? 0x00001000     : 0);
  301         r |=    ((l & IMAXBEL) ? 0x00002000     : 0);
  302         st->c_iflag = r;
  303 
  304         l = bt->c_oflag;
  305         r =     ((l &   OPOST) ? 0x00000001     : 0);
  306         /*      ((l &   OLCUC) ? 0x00000002     : 0) */
  307         r |=    ((l &   ONLCR) ? 0x00000004     : 0);
  308         /*      ((l &   OCRNL) ? 0x00000008     : 0) */
  309         /*      ((l &   ONOCR) ? 0x00000010     : 0) */
  310         /*      ((l &  ONLRET) ? 0x00000020     : 0) */
  311         /*      ((l &   OFILL) ? 0x00000040     : 0) */
  312         /*      ((l &   OFDEL) ? 0x00000080     : 0) */
  313         /*      ((l &   NLDLY) ? 0x00000100     : 0) */
  314         /*      ((l &     NL1) ? 0x00000100     : 0) */
  315         /*      ((l &   CRDLY) ? 0x00000600     : 0) */
  316         /*      ((l &     CR1) ? 0x00000200     : 0) */
  317         /*      ((l &     CR2) ? 0x00000400     : 0) */
  318         /*      ((l &     CR3) ? 0x00000600     : 0) */
  319         /*      ((l &  TABDLY) ? 0x00001800     : 0) */
  320         /*      ((l &    TAB1) ? 0x00000800     : 0) */
  321         /*      ((l &    TAB2) ? 0x00001000     : 0) */
  322         r |=    ((l &  OXTABS) ? 0x00001800     : 0);
  323         /*      ((l &   BSDLY) ? 0x00002000     : 0) */
  324         /*      ((l &     BS1) ? 0x00002000     : 0) */
  325         /*      ((l &   VTDLY) ? 0x00004000     : 0) */
  326         /*      ((l &     VT1) ? 0x00004000     : 0) */
  327         /*      ((l &   FFDLY) ? 0x00008000     : 0) */
  328         /*      ((l &     FF1) ? 0x00008000     : 0) */
  329         /*      ((l & PAGEOUT) ? 0x00010000     : 0) */
  330         /*      ((l &    WRAP) ? 0x00020000     : 0) */
  331         st->c_oflag = r;
  332 
  333         l = bt->c_cflag;
  334         switch (l & CSIZE) {
  335         case CS5:
  336                 r = 0;
  337                 break;
  338         case CS6:
  339                 r = 0x00000010;
  340                 break;
  341         case CS7:
  342                 r = 0x00000020;
  343                 break;
  344         case CS8:
  345                 r = 0x00000030;
  346                 break;
  347         }
  348         r |=    ((l &  CSTOPB) ? 0x00000040     : 0);
  349         r |=    ((l &   CREAD) ? 0x00000080     : 0);
  350         r |=    ((l &  PARENB) ? 0x00000100     : 0);
  351         r |=    ((l &  PARODD) ? 0x00000200     : 0);
  352         r |=    ((l &   HUPCL) ? 0x00000400     : 0);
  353         r |=    ((l &  CLOCAL) ? 0x00000800     : 0);
  354         /*      ((l &   LOBLK) ? 0x00001000     : 0) */
  355         r |=    ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
  356         st->c_cflag = r;
  357 
  358         l = bt->c_lflag;
  359         r =     ((l &    ISIG) ? 0x00000001     : 0);
  360         r |=    ((l &  ICANON) ? 0x00000002     : 0);
  361         /*      ((l &   XCASE) ? 0x00000004     : 0) */
  362         r |=    ((l &    ECHO) ? 0x00000008     : 0);
  363         r |=    ((l &   ECHOE) ? 0x00000010     : 0);
  364         r |=    ((l &   ECHOK) ? 0x00000020     : 0);
  365         r |=    ((l &  ECHONL) ? 0x00000040     : 0);
  366         r |=    ((l &  NOFLSH) ? 0x00000080     : 0);
  367         r |=    ((l &  TOSTOP) ? 0x00000100     : 0);
  368         r |=    ((l & ECHOCTL) ? 0x00000200     : 0);
  369         r |=    ((l & ECHOPRT) ? 0x00000400     : 0);
  370         r |=    ((l &  ECHOKE) ? 0x00000800     : 0);
  371         /*      ((l & DEFECHO) ? 0x00001000     : 0) */
  372         r |=    ((l &  FLUSHO) ? 0x00002000     : 0);
  373         r |=    ((l &  PENDIN) ? 0x00004000     : 0);
  374         st->c_lflag = r;
  375 
  376         s = ttspeedtab(bt->c_ospeed, sptab);
  377         if (s >= 0)
  378                 st->c_cflag |= s;
  379 
  380         st->c_cc[0] = bt->c_cc[VINTR]   != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
  381         st->c_cc[1] = bt->c_cc[VQUIT]   != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
  382         st->c_cc[2] = bt->c_cc[VERASE]  != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
  383         st->c_cc[3] = bt->c_cc[VKILL]   != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
  384         st->c_cc[4] = bt->c_cc[VEOF]    != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
  385         st->c_cc[5] = bt->c_cc[VEOL]    != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
  386         st->c_cc[6] = bt->c_cc[VEOL2]   != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
  387         st->c_cc[7] = 0;
  388                 /*    bt->c_cc[VSWTCH]  != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
  389         st->c_cc[8] = bt->c_cc[VSTART]  != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
  390         st->c_cc[9] = bt->c_cc[VSTOP]   != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
  391         st->c_cc[10]= bt->c_cc[VSUSP]   != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
  392         st->c_cc[11]= bt->c_cc[VDSUSP]  != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
  393         st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
  394         st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
  395         st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
  396         st->c_cc[15]= bt->c_cc[VLNEXT]  != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
  397         st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
  398 
  399         if (!(bt->c_lflag & ICANON)) {
  400                 /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
  401                 st->c_cc[4] = bt->c_cc[VMIN];
  402                 st->c_cc[5] = bt->c_cc[VTIME];
  403         }
  404 
  405         st->c_line = 0;
  406 }
  407 
  408 static void
  409 stios2stio(struct sunos_termios *ts, struct sunos_termio *t)
  410 {
  411         t->c_iflag = ts->c_iflag;
  412         t->c_oflag = ts->c_oflag;
  413         t->c_cflag = ts->c_cflag;
  414         t->c_lflag = ts->c_lflag;
  415         t->c_line  = ts->c_line;
  416         memcpy(t->c_cc, ts->c_cc, 8);
  417 }
  418 
  419 static void
  420 stio2stios(struct sunos_termio *t, struct sunos_termios *ts)
  421 {
  422         ts->c_iflag = t->c_iflag;
  423         ts->c_oflag = t->c_oflag;
  424         ts->c_cflag = t->c_cflag;
  425         ts->c_lflag = t->c_lflag;
  426         ts->c_line  = t->c_line;
  427         memcpy(ts->c_cc, t->c_cc, 8); /* don't touch the upper fields! */
  428 }
  429 
  430 
  431 static int
  432 sunos32_do_ioctl(int fd, int cmd, void *arg, struct lwp *l)
  433 {
  434         file_t *fp;
  435         struct vnode *vp;
  436         int error;
  437 
  438         if ((fp = fd_getfile(fd)) == NULL)
  439                 return EBADF;
  440         if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
  441                 fd_putfile(fd);
  442                 return EBADF;
  443         }
  444         error = fp->f_ops->fo_ioctl(fp, cmd, arg);
  445         if (error == EIO && cmd == TIOCGPGRP) {
  446                 vp = (struct vnode *)fp->f_data;
  447                 if (vp != NULL && vp->v_type == VCHR && major(vp->v_rdev) == 21)
  448                         error = ENOTTY;
  449         }
  450         fd_putfile(fd);
  451         return error;
  452 }
  453 
  454 int
  455 sunos32_sys_ioctl(struct lwp *l, const struct sunos32_sys_ioctl_args *uap, register_t *retval)
  456 {
  457         /* {
  458                 int     fd;
  459                 netbsd32_u_long com;
  460                 netbsd32_caddr_t        data;
  461         } */
  462         struct netbsd32_ioctl_args bsd_ua;
  463         int error;
  464 
  465         SCARG(&bsd_ua, fd) = SCARG(uap, fd);
  466         SCARG(&bsd_ua, com) = SCARG(uap, com);
  467         SCARG(&bsd_ua, data) = SCARG(uap, data);
  468 
  469         switch (SCARG(uap, com)) {
  470         case _IOR('t', 0, int):
  471                 SCARG(&bsd_ua, com) = TIOCGETD;
  472                 break;
  473         case _IOW('t', 1, int):
  474             {
  475                 int disc;
  476 
  477                 if ((error = copyin(SCARG_P32(uap, data), &disc,
  478                     sizeof disc)) != 0)
  479                         return error;
  480 
  481                 /* map SunOS NTTYDISC into our termios discipline */
  482                 if (disc == 2)
  483                         disc = 0;
  484                 /* all other disciplines are not supported by NetBSD */
  485                 if (disc)
  486                         return ENXIO;
  487 
  488                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSETD, &disc, l);
  489             }
  490         case _IOW('t', 101, int):       /* sun SUNOS_TIOCSSOFTCAR */
  491             {
  492                 int x;  /* unused */
  493 
  494                 return copyin(SCARG_P32(uap, data), &x, sizeof x);
  495             }
  496         case _IOR('t', 100, int):       /* sun SUNOS_TIOCSSOFTCAR */
  497             {
  498                 int x = 0;
  499 
  500                 return copyout(&x, SCARG_P32(uap, data), sizeof x);
  501             }
  502         case _IO('t', 36):              /* sun TIOCCONS, no parameters */
  503             {
  504                 int on = 1;
  505                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCCONS, &on, l);
  506             }
  507         case _IOW('t', 37, struct sunos_ttysize):
  508             {
  509                 struct winsize ws;
  510                 struct sunos_ttysize ss;
  511 
  512                 if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws, l)) != 0)
  513                         return (error);
  514 
  515                 if ((error = copyin(SCARG_P32(uap, data), &ss, sizeof (ss))) != 0)
  516                         return error;
  517 
  518                 ws.ws_row = ss.ts_row;
  519                 ws.ws_col = ss.ts_col;
  520 
  521                 return (sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSWINSZ, &ws, l));
  522             }
  523         case _IOW('t', 38, struct sunos_ttysize):
  524             {
  525                 struct winsize ws;
  526                 struct sunos_ttysize ss;
  527 
  528                 if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws, l)) != 0)
  529                         return (error);
  530 
  531                 ss.ts_row = ws.ws_row;
  532                 ss.ts_col = ws.ws_col;
  533 
  534                 return copyout(&ss, SCARG_P32(uap, data), sizeof (ss));
  535             }
  536         case _IOW('t', 130, int):       /* TIOCSETPGRP: posix variant */
  537                 SCARG(&bsd_ua, com) = TIOCSPGRP;
  538                 break;
  539         case _IOR('t', 131, int):       /* TIOCGETPGRP: posix variant */
  540             {
  541                 /*
  542                  * sigh, must do error translation on pty devices
  543                  * (see also kern/tty_pty.c)
  544                  */
  545                 int pgrp;
  546                 error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGPGRP, &pgrp, l);
  547                 if (error)
  548                         return (error);
  549                 return copyout(&pgrp, SCARG_P32(uap, data), sizeof(pgrp));
  550             }
  551         case _IO('t', 132):
  552                 SCARG(&bsd_ua, com) = TIOCSCTTY;
  553                 break;
  554         case SUNOS_TCGETA:
  555         case SUNOS_TCGETS:
  556             {
  557                 struct termios bts;
  558                 struct sunos_termios sts;
  559                 struct sunos_termio st;
  560 
  561                 if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA, &bts, l)) != 0)
  562                         return error;
  563 
  564                 btios2stios (&bts, &sts);
  565                 if (SCARG(uap, com) == SUNOS_TCGETA) {
  566                         stios2stio (&sts, &st);
  567                         return copyout(&st, SCARG_P32(uap, data),
  568                             sizeof (st));
  569                 } else
  570                         return copyout(&sts, SCARG_P32(uap, data),
  571                             sizeof (sts));
  572                 /*NOTREACHED*/
  573             }
  574         case SUNOS_TCSETA:
  575         case SUNOS_TCSETAW:
  576         case SUNOS_TCSETAF:
  577             {
  578                 struct termios bts;
  579                 struct sunos_termios sts;
  580                 struct sunos_termio st;
  581 
  582                 if ((error = copyin(SCARG_P32(uap, data), &st,
  583                     sizeof (st))) != 0)
  584                         return error;
  585 
  586                 /* get full BSD termios so we don't lose information */
  587                 if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA, &bts, l)) != 0)
  588                         return error;
  589 
  590                 /*
  591                  * convert to sun termios, copy in information from
  592                  * termio, and convert back, then set new values.
  593                  */
  594                 btios2stios(&bts, &sts);
  595                 stio2stios(&st, &sts);
  596                 stios2btios(&sts, &bts);
  597 
  598                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA,
  599                     &bts, l);
  600             }
  601         case SUNOS_TCSETS:
  602         case SUNOS_TCSETSW:
  603         case SUNOS_TCSETSF:
  604             {
  605                 struct termios bts;
  606                 struct sunos_termios sts;
  607 
  608                 if ((error = copyin(SCARG_P32(uap, data), &sts,
  609                     sizeof (sts))) != 0)
  610                         return error;
  611                 stios2btios (&sts, &bts);
  612                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA,
  613                     &bts, l);
  614             }
  615 /*
  616  * Pseudo-tty ioctl translations.
  617  */
  618         case _IOW('t', 32, int): {      /* TIOCTCNTL */
  619                 int error1, on;
  620 
  621                 error1 = copyin(SCARG_P32(uap, data), &on, sizeof (on));
  622                 if (error1)
  623                         return error1;
  624                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCUCNTL, &on, l);
  625         }
  626         case _IOW('t', 33, int): {      /* TIOCSIGNAL */
  627                 int error1, sig;
  628 
  629                 error1 = copyin(SCARG_P32(uap, data), &sig, sizeof (sig));
  630                 if (error1)
  631                         return error1;
  632                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSIG, &sig, l);
  633         }
  634 
  635 /*
  636  * Socket ioctl translations.
  637  */
  638 #define IFREQ_IN(a) { \
  639         struct oifreq ifreq; \
  640         error = copyin(SCARG_P32(uap, data), &ifreq, sizeof (ifreq)); \
  641         if (error) \
  642                 return error; \
  643         return sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l); \
  644 }
  645 #define IFREQ_INOUT(a) { \
  646         struct oifreq ifreq; \
  647         error = copyin(SCARG_P32(uap, data), &ifreq, sizeof (ifreq)); \
  648         if (error) \
  649                 return error; \
  650         if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l)) != 0) \
  651                 return error; \
  652         return copyout(&ifreq, SCARG_P32(uap, data), sizeof (ifreq)); \
  653 }
  654 
  655         case _IOW('i', 12, struct oifreq):
  656                 /* SIOCSIFADDR */
  657                 break;
  658 
  659         case _IOWR('i', 13, struct oifreq):
  660                 IFREQ_INOUT(OOSIOCGIFADDR);
  661 
  662         case _IOW('i', 14, struct oifreq):
  663                 /* SIOCSIFDSTADDR */
  664                 break;
  665 
  666         case _IOWR('i', 15, struct oifreq):
  667                 IFREQ_INOUT(OOSIOCGIFDSTADDR);
  668 
  669         case _IOW('i', 16, struct oifreq):
  670                 /* SIOCSIFFLAGS */
  671                 break;
  672 
  673         case _IOWR('i', 17, struct oifreq):
  674                 /* SIOCGIFFLAGS */
  675                 break;
  676 
  677         case _IOW('i', 21, struct oifreq):
  678                 IFREQ_IN(SIOCSIFMTU);
  679 
  680         case _IOWR('i', 22, struct oifreq):
  681                 IFREQ_INOUT(SIOCGIFMTU);
  682 
  683         case _IOWR('i', 23, struct oifreq):
  684                 IFREQ_INOUT(SIOCGIFBRDADDR);
  685 
  686         case _IOW('i', 24, struct oifreq):
  687                 IFREQ_IN(SIOCSIFBRDADDR);
  688 
  689         case _IOWR('i', 25, struct oifreq):
  690                 IFREQ_INOUT(OOSIOCGIFNETMASK);
  691 
  692         case _IOW('i', 26, struct oifreq):
  693                 IFREQ_IN(SIOCSIFNETMASK);
  694 
  695         case _IOWR('i', 27, struct oifreq):
  696                 IFREQ_INOUT(SIOCGIFMETRIC);
  697 
  698         case _IOWR('i', 28, struct oifreq):
  699                 IFREQ_IN(SIOCSIFMETRIC);
  700 
  701         case _IOW('i', 30, struct arpreq):
  702                 /* SIOCSARP */
  703                 break;
  704 
  705         case _IOWR('i', 31, struct arpreq):
  706                 /* SIOCGARP */
  707                 break;
  708 
  709         case _IOW('i', 32, struct arpreq):
  710                 /* SIOCDARP */
  711                 break;
  712 
  713         case _IOW('i', 18, struct oifreq):      /* SIOCSIFMEM */
  714         case _IOWR('i', 19, struct oifreq):     /* SIOCGIFMEM */
  715         case _IOW('i', 40, struct oifreq):      /* SIOCUPPER */
  716         case _IOW('i', 41, struct oifreq):      /* SIOCLOWER */
  717         case _IOW('i', 44, struct oifreq):      /* SIOCSETSYNC */
  718         case _IOWR('i', 45, struct oifreq):     /* SIOCGETSYNC */
  719         case _IOWR('i', 46, struct oifreq):     /* SIOCSDSTATS */
  720         case _IOWR('i', 47, struct oifreq):     /* SIOCSESTATS */
  721         case _IOW('i', 48, int):                /* SIOCSPROMISC */
  722         case _IOW('i', 49, struct oifreq):      /* SIOCADDMULTI */
  723         case _IOW('i', 50, struct oifreq):      /* SIOCDELMULTI */
  724                 return EOPNOTSUPP;
  725 
  726         case _IOWR('i', 20, struct oifconf):    /* SIOCGIFCONF */
  727             {
  728                 struct oifconf ifcf;
  729 
  730                 /*
  731                  * XXX: two more problems
  732                  * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
  733                  * 2. this returns a name per protocol, ie. it returns two "lo0"'s
  734                  */
  735                 error = copyin(SCARG_P32(uap, data), &ifcf,
  736                     sizeof (ifcf));
  737                 if (error)
  738                         return error;
  739                 error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), OOSIOCGIFCONF, &ifcf, l);
  740                 if (error)
  741                         return error;
  742                 return copyout(&ifcf, SCARG_P32(uap, data),
  743                     sizeof (ifcf));
  744             }
  745 
  746 /*
  747  * Audio ioctl translations.
  748  */
  749         case _IOR('A', 1, struct sunos_audio_info):     /* AUDIO_GETINFO */
  750         sunos_au_getinfo:
  751             {
  752                 struct audio_info aui;
  753                 struct sunos_audio_info sunos_aui;
  754 
  755                 error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_GETINFO, &aui, l);
  756                 if (error)
  757                         return error;
  758 
  759                 sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play;
  760                 sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record;
  761 
  762                 /* `avail_ports' is `seek' in BSD */
  763                 sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
  764                 sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
  765 
  766                 sunos_aui.play.waiting = 0;
  767                 sunos_aui.record.waiting = 0;
  768                 sunos_aui.play.eof = 0;
  769                 sunos_aui.record.eof = 0;
  770                 sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */
  771                 /*XXXsunos_aui.output_muted = 0;*/
  772                 /*XXX*/sunos_aui.reserved[0] = 0;
  773                 /*XXX*/sunos_aui.reserved[1] = 0;
  774                 /*XXX*/sunos_aui.reserved[2] = 0;
  775                 /*XXX*/sunos_aui.reserved[3] = 0;
  776 
  777                 return copyout(&sunos_aui, SCARG_P32(uap, data),
  778                                 sizeof (sunos_aui));
  779             }
  780 
  781         case _IOWR('A', 2, struct sunos_audio_info):    /* AUDIO_SETINFO */
  782             {
  783                 struct audio_info aui;
  784                 struct sunos_audio_info sunos_aui;
  785 
  786                 error = copyin(SCARG_P32(uap, data), &sunos_aui,
  787                     sizeof (sunos_aui));
  788                 if (error)
  789                         return error;
  790 
  791                 aui.play = *(struct audio_prinfo *)&sunos_aui.play;
  792                 aui.record = *(struct audio_prinfo *)&sunos_aui.record;
  793                 /* aui.__spare = sunos_aui.monitor_gain; */
  794                 aui.blocksize = ~0;
  795                 aui.hiwat = ~0;
  796                 aui.lowat = ~0;
  797                 /* XXX somebody check this please. - is: aui.backlog = ~0; */
  798                 aui.mode = ~0;
  799                 /*
  800                  * The bsd driver does not distinguish between paused and
  801                  * active. (In the sun driver, not active means samples are
  802                  * not output at all, but paused means the last streams buffer
  803                  * is drained and then output stops.)  If either are 0, then
  804                  * when stop output. Otherwise, if either are non-zero,
  805                  * we resume.
  806                  */
  807                 if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0)
  808                         aui.play.pause = 0;
  809                 else if (sunos_aui.play.pause != (u_char)~0 ||
  810                          sunos_aui.play.active != (u_char)~0)
  811                         aui.play.pause = 1;
  812                 if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0)
  813                         aui.record.pause = 0;
  814                 else if (sunos_aui.record.pause != (u_char)~0 ||
  815                          sunos_aui.record.active != (u_char)~0)
  816                         aui.record.pause = 1;
  817 
  818                 error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_SETINFO, &aui, l);
  819                 if (error)
  820                         return error;
  821                 /* Return new state */
  822                 goto sunos_au_getinfo;
  823             }
  824         case _IO('A', 3):       /* AUDIO_DRAIN */
  825                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_DRAIN, NULL, l);
  826         case _IOR('A', 4, int): /* AUDIO_GETDEV */
  827             {
  828                 int devtype = SUNOS_AUDIO_DEV_AMD;
  829                 return copyout(&devtype, SCARG_P32(uap, data),
  830                                 sizeof (devtype));
  831             }
  832 
  833 /*
  834  * Selected streams ioctls.
  835  */
  836 #define SUNOS_S_FLUSHR          1
  837 #define SUNOS_S_FLUSHW          2
  838 #define SUNOS_S_FLUSHRW         3
  839 
  840 #define SUNOS_S_INPUT           1
  841 #define SUNOS_S_HIPRI           2
  842 #define SUNOS_S_OUTPUT          4
  843 #define SUNOS_S_MSG             8
  844 
  845         case _IO('S', 5):       /* I_FLUSH */
  846             {
  847                 int tmp = 0;
  848                 switch ((intptr_t)SCARG_P32(uap, data)) {
  849                 case SUNOS_S_FLUSHR:    tmp = FREAD;
  850                 case SUNOS_S_FLUSHW:    tmp = FWRITE;
  851                 case SUNOS_S_FLUSHRW:   tmp = FREAD|FWRITE;
  852                 }
  853                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCFLUSH, &tmp, l);
  854             }
  855         case _IO('S', 9):       /* I_SETSIG */
  856             {
  857                 int on = 1;
  858                 if (((intptr_t)SCARG_P32(uap, data) &
  859                         (SUNOS_S_HIPRI|SUNOS_S_INPUT)) ==
  860                     SUNOS_S_HIPRI)
  861                         return EOPNOTSUPP;
  862                 return sunos32_do_ioctl(SCARG(&bsd_ua, fd), FIOASYNC, &on, l);
  863             }
  864         /*
  865          * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c
  866          * (which was from the old sparc/scsi/sun_disklabel.c), and
  867          * modified to suite.
  868          */
  869         case DKIOCGGEOM:
  870             {
  871                 struct disklabel dl;
  872 
  873                 error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), DIOCGDINFO, &dl, l);
  874                 if (error)
  875                         return (error);
  876 
  877 #define datageom        ((struct sun_dkgeom *)SCARG_P32(uap, data))
  878                 /* XXX can't do memset() on a user address (dsl) */
  879                 memset(SCARG_P32(uap, data), 0, sizeof(*datageom));
  880 
  881                 datageom->sdkc_ncylinders = dl.d_ncylinders;
  882                 datageom->sdkc_acylinders = dl.d_acylinders;
  883                 datageom->sdkc_ntracks = dl.d_ntracks;
  884                 datageom->sdkc_nsectors = dl.d_nsectors;
  885                 datageom->sdkc_interleave = dl.d_interleave;
  886                 datageom->sdkc_sparespercyl = dl.d_sparespercyl;
  887                 datageom->sdkc_rpm = dl.d_rpm;
  888                 datageom->sdkc_pcylinders = dl.d_ncylinders + dl.d_acylinders;
  889 #undef datageom
  890                 break;
  891             }
  892 
  893         case DKIOCINFO:
  894                 /* Homey don't do DKIOCINFO */
  895                 /* XXX can't do memset() on a user address (dsl) */
  896                 memset(SCARG_P32(uap, data), 0, sizeof(struct sun_dkctlr));
  897                 break;
  898 
  899         case DKIOCGPART:
  900             {
  901                 struct partinfo pi;
  902 
  903                 error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), DIOCGPART, &pi, l);
  904                 if (error)
  905                         return (error);
  906 
  907                 if (pi.disklab->d_secpercyl == 0)
  908                         return (ERANGE);        /* XXX */
  909                 if (pi.part->p_offset % pi.disklab->d_secpercyl != 0)
  910                         return (ERANGE);        /* XXX */
  911                 /* XXX can't do direct writes to a user address (dsl) */
  912 #define datapart        ((struct sun_dkpart *)SCARG_P32(uap, data))
  913                 datapart->sdkp_cyloffset = pi.part->p_offset / pi.disklab->d_secpercyl;
  914                 datapart->sdkp_nsectors = pi.part->p_size;
  915 #undef datapart
  916             }
  917 
  918         }
  919         return (netbsd32_ioctl(l, &bsd_ua, retval));
  920 }
  921 
  922 /* SunOS fcntl(2) cmds not implemented */
  923 #define SUN_F_RGETLK    10
  924 #define SUN_F_RSETLK    11
  925 #define SUN_F_CNVT      12
  926 #define SUN_F_RSETLKW   13
  927 
  928 /* SunOS flock translation */
  929 struct sunos_flock {
  930         short   l_type;
  931         short   l_whence;
  932         netbsd32_long   l_start;
  933         netbsd32_long   l_len;
  934         short   l_pid;
  935         short   l_xxx;
  936 };
  937 
  938 static void bsd_to_sunos_flock(struct flock *, struct sunos_flock *);
  939 static void sunos_to_bsd_flock(struct sunos_flock *, struct flock *);
  940 
  941 #define SUNOS_F_RDLCK   1
  942 #define SUNOS_F_WRLCK   2
  943 #define SUNOS_F_UNLCK   3
  944 
  945 static void
  946 bsd_to_sunos_flock(struct flock *iflp, struct sunos_flock *oflp)
  947 {
  948         switch (iflp->l_type) {
  949         case F_RDLCK:
  950                 oflp->l_type = SUNOS_F_RDLCK;
  951                 break;
  952         case F_WRLCK:
  953                 oflp->l_type = SUNOS_F_WRLCK;
  954                 break;
  955         case F_UNLCK:
  956                 oflp->l_type = SUNOS_F_UNLCK;
  957                 break;
  958         default:
  959                 oflp->l_type = -1;
  960                 break;
  961         }
  962 
  963         oflp->l_whence = (short) iflp->l_whence;
  964         oflp->l_start = (netbsd32_long) iflp->l_start;
  965         oflp->l_len = (netbsd32_long) iflp->l_len;
  966         oflp->l_pid = (short) iflp->l_pid;
  967         oflp->l_xxx = 0;
  968 }
  969 
  970 
  971 static void
  972 sunos_to_bsd_flock(struct sunos_flock *iflp, struct flock *oflp)
  973 {
  974         switch (iflp->l_type) {
  975         case SUNOS_F_RDLCK:
  976                 oflp->l_type = F_RDLCK;
  977                 break;
  978         case SUNOS_F_WRLCK:
  979                 oflp->l_type = F_WRLCK;
  980                 break;
  981         case SUNOS_F_UNLCK:
  982                 oflp->l_type = F_UNLCK;
  983                 break;
  984         default:
  985                 oflp->l_type = -1;
  986                 break;
  987         }
  988 
  989         oflp->l_whence = iflp->l_whence;
  990         oflp->l_start = (off_t) iflp->l_start;
  991         oflp->l_len = (off_t) iflp->l_len;
  992         oflp->l_pid = (pid_t) iflp->l_pid;
  993 
  994 }
  995 static struct {
  996         netbsd32_long   sun_flg;
  997         netbsd32_long   bsd_flg;
  998 } sunfcntl_flgtab[] = {
  999         /* F_[GS]ETFLags that differ: */
 1000 #define SUN_FSETBLK     0x0010
 1001 #define SUN_SHLOCK      0x0080
 1002 #define SUN_EXLOCK      0x0100
 1003 #define SUN_FNBIO       0x1000
 1004 #define SUN_FSYNC       0x2000
 1005 #define SUN_NONBLOCK    0x4000
 1006 #define SUN_FNOCTTY     0x8000
 1007         { SUN_NONBLOCK, O_NONBLOCK },
 1008         { SUN_FNBIO, O_NONBLOCK },
 1009         { SUN_SHLOCK, O_SHLOCK },
 1010         { SUN_EXLOCK, O_EXLOCK },
 1011         { SUN_FSYNC, O_FSYNC },
 1012         { SUN_FSETBLK, 0 },
 1013         { SUN_FNOCTTY, 0 }
 1014 };
 1015 
 1016 int
 1017 sunos32_sys_fcntl(struct lwp *l, const struct sunos32_sys_fcntl_args *uap, register_t *retval)
 1018 {
 1019         /* {
 1020                 syscallarg(int) fd;
 1021                 syscallarg(int) cmd;
 1022                 syscallarg(netbsd32_voidp) arg;
 1023         } */
 1024         struct sys_fcntl_args bsd_ua;
 1025         uintptr_t flg;
 1026         int n, ret;
 1027 
 1028         SCARG(&bsd_ua, fd) = SCARG(uap, fd);
 1029         SCARG(&bsd_ua, cmd) = SCARG(uap, cmd);
 1030         SCARG(&bsd_ua, arg) = SCARG_P32(uap, arg);
 1031 
 1032         switch (SCARG(uap, cmd)) {
 1033         case F_SETFL:
 1034                 flg = (intptr_t)SCARG_P32(uap, arg);
 1035                 n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
 1036                 while (--n >= 0) {
 1037                         if (flg & sunfcntl_flgtab[n].sun_flg) {
 1038                                 flg &= ~sunfcntl_flgtab[n].sun_flg;
 1039                                 flg |= sunfcntl_flgtab[n].bsd_flg;
 1040                         }
 1041                 }
 1042                 SCARG(&bsd_ua, arg) = (void *)flg;
 1043                 break;
 1044 
 1045         case F_GETLK:
 1046         case F_SETLK:
 1047         case F_SETLKW:
 1048                 {
 1049                         int error;
 1050                         struct sunos_flock      ifl;
 1051                         struct flock            fl;
 1052 
 1053                         error = copyin(SCARG_P32(uap, arg), &ifl, sizeof ifl);
 1054                         if (error)
 1055                                 return error;
 1056                         sunos_to_bsd_flock(&ifl, &fl);
 1057 
 1058                         error = do_fcntl_lock(SCARG(uap, fd), SCARG(uap, cmd), &fl);
 1059                         if (error || SCARG(uap, cmd) != F_GETLK)
 1060                                 return error;
 1061 
 1062                         bsd_to_sunos_flock(&fl, &ifl);
 1063                         return copyout(&ifl, SCARG_P32(uap, arg), sizeof ifl);
 1064                 }
 1065                 break;
 1066         case SUN_F_RGETLK:
 1067         case SUN_F_RSETLK:
 1068         case SUN_F_CNVT:
 1069         case SUN_F_RSETLKW:
 1070                 return (EOPNOTSUPP);
 1071         }
 1072 
 1073         ret = sys_fcntl(l, &bsd_ua, retval);
 1074         if (ret != 0)
 1075                 return ret;
 1076 
 1077         switch (SCARG(uap, cmd)) {
 1078         case F_GETFL:
 1079                 n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
 1080                 ret = *retval;
 1081                 while (--n >= 0) {
 1082                         if (ret & sunfcntl_flgtab[n].bsd_flg) {
 1083                                 ret &= ~sunfcntl_flgtab[n].bsd_flg;
 1084                                 ret |= sunfcntl_flgtab[n].sun_flg;
 1085                         }
 1086                 }
 1087                 *retval = ret;
 1088                 break;
 1089         }
 1090 
 1091         return 0;
 1092 }

Cache object: 9fd08e7d25c3dafbb0c4947931ffe03e


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