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/svr4/svr4_stream.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: svr4_stream.c,v 1.60 2006/11/16 01:32:44 christos Exp $         */
    2 
    3 /*-
    4  * Copyright (c) 1994 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas.
    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 /*
   40  * Pretend that we have streams...
   41  * Yes, this is gross.
   42  *
   43  * ToDo: The state machine for getmsg needs re-thinking
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 __KERNEL_RCSID(0, "$NetBSD: svr4_stream.c,v 1.60 2006/11/16 01:32:44 christos Exp $");
   48 
   49 #include <sys/param.h>
   50 #include <sys/kernel.h>
   51 #include <sys/systm.h>
   52 #include <sys/buf.h>
   53 #include <sys/malloc.h>
   54 #include <sys/ioctl.h>
   55 #include <sys/tty.h>
   56 #include <sys/file.h>
   57 #include <sys/filedesc.h>
   58 #include <sys/select.h>
   59 #include <sys/socket.h>
   60 #include <sys/socketvar.h>
   61 #include <sys/un.h>
   62 #include <net/if.h>
   63 #include <netinet/in.h>
   64 #include <sys/mount.h>
   65 #include <sys/proc.h>
   66 #include <sys/vnode.h>
   67 #include <sys/device.h>
   68 #include <sys/stat.h>
   69 
   70 #include <sys/sa.h>
   71 #include <sys/syscallargs.h>
   72 
   73 #include <compat/svr4/svr4_types.h>
   74 #include <compat/svr4/svr4_util.h>
   75 #include <compat/svr4/svr4_signal.h>
   76 #include <compat/svr4/svr4_lwp.h>
   77 #include <compat/svr4/svr4_ucontext.h>
   78 #include <compat/svr4/svr4_syscallargs.h>
   79 #include <compat/svr4/svr4_stropts.h>
   80 #include <compat/svr4/svr4_timod.h>
   81 #include <compat/svr4/svr4_sockmod.h>
   82 #include <compat/svr4/svr4_ioctl.h>
   83 #include <compat/svr4/svr4_socket.h>
   84 
   85 
   86 /* Utils */
   87 static int clean_pipe __P((struct lwp *, const char *));
   88 static void getparm __P((struct file *, struct svr4_si_sockparms *));
   89 
   90 /* Address Conversions */
   91 static void sockaddr_to_netaddr_in __P((struct svr4_strmcmd *,
   92                                         const struct sockaddr_in *));
   93 static void sockaddr_to_netaddr_un __P((struct svr4_strmcmd *,
   94                                         const struct sockaddr_un *));
   95 static void netaddr_to_sockaddr_in __P((struct sockaddr_in *,
   96                                         const struct svr4_strmcmd *));
   97 static void netaddr_to_sockaddr_un __P((struct sockaddr_un *,
   98                                         const struct svr4_strmcmd *));
   99 
  100 /* stream ioctls */
  101 static int i_nread __P((struct file *, struct lwp *, register_t *, int,
  102     u_long, caddr_t));
  103 static int i_fdinsert __P((struct file *, struct lwp *, register_t *, int,
  104     u_long, caddr_t));
  105 static int i_str __P((struct file *, struct lwp *, register_t *, int,
  106     u_long, caddr_t));
  107 static int i_setsig __P((struct file *, struct lwp *, register_t *, int,
  108     u_long, caddr_t));
  109 static int i_getsig __P((struct file *, struct lwp *, register_t *, int,
  110     u_long, caddr_t));
  111 static int _i_bind_rsvd __P((struct file *, struct lwp *, register_t *, int,
  112     u_long, caddr_t));
  113 static int _i_rele_rsvd __P((struct file *, struct lwp *, register_t *, int,
  114     u_long, caddr_t));
  115 
  116 /* i_str sockmod calls */
  117 static int sockmod       __P((struct file *, int, struct svr4_strioctl *,
  118                               struct lwp *));
  119 static int si_listen     __P((struct file *, int, struct svr4_strioctl *,
  120                               struct lwp *));
  121 static int si_ogetudata  __P((struct file *, int, struct svr4_strioctl *,
  122                               struct lwp *));
  123 static int si_sockparams __P((struct file *, int, struct svr4_strioctl *,
  124                               struct lwp *));
  125 static int si_shutdown   __P((struct file *, int, struct svr4_strioctl *,
  126                               struct lwp *));
  127 static int si_getudata   __P((struct file *, int, struct svr4_strioctl *,
  128                               struct lwp *));
  129 
  130 /* i_str timod calls */
  131 static int timod         __P((struct file *, int, struct svr4_strioctl *,
  132                               struct lwp *));
  133 static int ti_getinfo    __P((struct file *, int, struct svr4_strioctl *,
  134                               struct lwp *));
  135 static int ti_bind       __P((struct file *, int, struct svr4_strioctl *,
  136                               struct lwp *));
  137 
  138 #ifdef DEBUG_SVR4
  139 static void bufprint __P((u_char *, size_t));
  140 static int show_ioc __P((const char *, struct svr4_strioctl *));
  141 static int show_strbuf __P((struct svr4_strbuf *));
  142 static void show_msg __P((const char *, int, struct svr4_strbuf *,
  143                           struct svr4_strbuf *, int));
  144 
  145 static void
  146 bufprint(buf, len)
  147         u_char *buf;
  148         size_t len;
  149 {
  150         size_t i;
  151 
  152         uprintf("\n\t");
  153         for (i = 0; i < len; i++) {
  154                 uprintf("%x ", buf[i]);
  155                 if (i && (i % 16) == 0)
  156                         uprintf("\n\t");
  157         }
  158 }
  159 
  160 static int
  161 show_ioc(str, ioc)
  162         const char              *str;
  163         struct svr4_strioctl    *ioc;
  164 {
  165         u_char *ptr;
  166         int error, len;
  167 
  168         len = ioc->len;
  169         if (len > 1024)
  170                 len = 1024;
  171 
  172         ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
  173         uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ",
  174             str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf);
  175 
  176         if ((error = copyin(ioc->buf, ptr, len)) != 0) {
  177                 free((char *) ptr, M_TEMP);
  178                 return error;
  179         }
  180 
  181         bufprint(ptr, len);
  182 
  183         uprintf("}\n");
  184 
  185         free((char *) ptr, M_TEMP);
  186         return 0;
  187 }
  188 
  189 
  190 static int
  191 show_strbuf(str)
  192         struct svr4_strbuf *str;
  193 {
  194         int error;
  195         u_char *ptr = NULL;
  196         int maxlen = str->maxlen;
  197         int len = str->len;
  198 
  199         if (maxlen > 8192)
  200                 maxlen = 8192;
  201 
  202         if (maxlen < 0)
  203                 maxlen = 0;
  204 
  205         if (len >= maxlen)
  206                 len = maxlen;
  207 
  208         if (len > 0) {
  209             ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
  210 
  211             if ((error = copyin(str->buf, ptr, len)) != 0) {
  212                     free((char *) ptr, M_TEMP);
  213                     return error;
  214             }
  215         }
  216 
  217         uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf);
  218 
  219         if (ptr)
  220                 bufprint(ptr, len);
  221 
  222         uprintf("]}");
  223 
  224         if (ptr)
  225                 free((char *) ptr, M_TEMP);
  226 
  227         return 0;
  228 }
  229 
  230 
  231 static void
  232 show_msg(str, fd, ctl, dat, flags)
  233         const char              *str;
  234         int                      fd;
  235         struct svr4_strbuf      *ctl;
  236         struct svr4_strbuf      *dat;
  237         int                      flags;
  238 {
  239         struct svr4_strbuf      buf;
  240         int error;
  241 
  242         uprintf("%s(%d", str, fd);
  243         if (ctl != NULL) {
  244                 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0)
  245                         return;
  246                 show_strbuf(&buf);
  247         }
  248         else
  249                 uprintf(", NULL");
  250 
  251         if (dat != NULL) {
  252                 if ((error = copyin(dat, &buf, sizeof(buf))) != 0)
  253                         return;
  254                 show_strbuf(&buf);
  255         }
  256         else
  257                 uprintf(", NULL");
  258 
  259         uprintf(", %x);\n", flags);
  260 }
  261 
  262 #endif /* DEBUG_SVR4 */
  263 
  264 
  265 /*
  266  * We are faced with an interesting situation. On svr4 unix sockets
  267  * are really pipes. But we really have sockets, and we might as
  268  * well use them. At the point where svr4 calls TI_BIND, it has
  269  * already created a named pipe for the socket using mknod(2).
  270  * We need to create a socket with the same name when we bind,
  271  * so we need to remove the pipe before, otherwise we'll get address
  272  * already in use. So we *carefully* remove the pipe, to avoid
  273  * using this as a random file removal tool. We use system calls
  274  * to avoid code duplication.
  275  */
  276 static int
  277 clean_pipe(l, path)
  278         struct lwp *l;
  279         const char *path;
  280 {
  281         struct proc *p = l->l_proc;
  282         struct sys___lstat30_args la;
  283         struct sys_unlink_args ua;
  284         register_t retval;
  285         struct stat st;
  286         int error;
  287         caddr_t sg = stackgap_init(p, 0);
  288         size_t len = strlen(path) + 1;
  289         void *tpath;
  290 
  291         tpath = stackgap_alloc(p, &sg, len);
  292         SCARG(&la, ub) = stackgap_alloc(p, &sg, sizeof(struct stat));
  293 
  294         if ((error = copyout(path, tpath, len)) != 0)
  295                 return error;
  296 
  297         SCARG(&la, path) = tpath;
  298 
  299         if ((error = sys___lstat30(l, &la, &retval)) != 0)
  300                 return 0;
  301 
  302         if ((error = copyin(SCARG(&la, ub), &st, sizeof(st))) != 0)
  303                 return 0;
  304 
  305         /*
  306          * Make sure we are dealing with a mode 0 named pipe.
  307          */
  308         if ((st.st_mode & S_IFMT) != S_IFIFO)
  309                 return 0;
  310 
  311         if ((st.st_mode & ALLPERMS) != 0)
  312                 return 0;
  313 
  314 
  315         SCARG(&ua, path) = SCARG(&la, path);
  316 
  317         if ((error = sys_unlink(l, &ua, &retval)) != 0) {
  318                 DPRINTF(("clean_pipe: unlink failed %d\n", error));
  319                 return error;
  320         }
  321 
  322         return 0;
  323 }
  324 
  325 
  326 static void
  327 sockaddr_to_netaddr_in(sc, sain)
  328         struct svr4_strmcmd *sc;
  329         const struct sockaddr_in *sain;
  330 {
  331         struct svr4_netaddr_in *na;
  332         na = SVR4_ADDROF(sc);
  333 
  334         na->family = sain->sin_family;
  335         na->port = sain->sin_port;
  336         na->addr = sain->sin_addr.s_addr;
  337         DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port,
  338                  na->addr));
  339 }
  340 
  341 
  342 static void
  343 sockaddr_to_netaddr_un(sc, saun)
  344         struct svr4_strmcmd *sc;
  345         const struct sockaddr_un *saun;
  346 {
  347         struct svr4_netaddr_un *na;
  348         char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1  -
  349             sizeof(*sc);
  350         const char *src;
  351 
  352         na = SVR4_ADDROF(sc);
  353         na->family = saun->sun_family;
  354         for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; )
  355                 if (dst == edst)
  356                         break;
  357         DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path));
  358 }
  359 
  360 
  361 static void
  362 netaddr_to_sockaddr_in(sain, sc)
  363         struct sockaddr_in *sain;
  364         const struct svr4_strmcmd *sc;
  365 {
  366         const struct svr4_netaddr_in *na;
  367 
  368 
  369         na = SVR4_C_ADDROF(sc);
  370         memset(sain, 0, sizeof(*sain));
  371         sain->sin_len = sizeof(*sain);
  372         sain->sin_family = na->family;
  373         sain->sin_port = na->port;
  374         sain->sin_addr.s_addr = na->addr;
  375         DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family,
  376                  sain->sin_port, sain->sin_addr.s_addr));
  377 }
  378 
  379 
  380 static void
  381 netaddr_to_sockaddr_un(saun, sc)
  382         struct sockaddr_un *saun;
  383         const struct svr4_strmcmd *sc;
  384 {
  385         const struct svr4_netaddr_un *na;
  386         char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1];
  387         const char *src;
  388 
  389         na = SVR4_C_ADDROF(sc);
  390         memset(saun, 0, sizeof(*saun));
  391         saun->sun_family = na->family;
  392         for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; )
  393                 if (dst == edst)
  394                         break;
  395         saun->sun_len = dst - saun->sun_path;
  396         DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family,
  397                  saun->sun_path));
  398 }
  399 
  400 
  401 static void
  402 getparm(fp, pa)
  403         struct file *fp;
  404         struct svr4_si_sockparms *pa;
  405 {
  406         struct svr4_strm *st = svr4_stream_get(fp);
  407         struct socket *so = (struct socket *) fp->f_data;
  408 
  409         if (st == NULL)
  410                 return;
  411 
  412         pa->family = st->s_family;
  413 
  414         switch (so->so_type) {
  415         case SOCK_DGRAM:
  416                 pa->type = SVR4_T_CLTS;
  417                 pa->protocol = IPPROTO_UDP;
  418                 DPRINTF(("getparm(dgram)\n"));
  419                 return;
  420 
  421         case SOCK_STREAM:
  422                 pa->type = SVR4_T_COTS;  /* What about T_COTS_ORD? XXX */
  423                 pa->protocol = IPPROTO_IP;
  424                 DPRINTF(("getparm(stream)\n"));
  425                 return;
  426 
  427         case SOCK_RAW:
  428                 pa->type = SVR4_T_CLTS;
  429                 pa->protocol = IPPROTO_RAW;
  430                 DPRINTF(("getparm(raw)\n"));
  431                 return;
  432 
  433         default:
  434                 pa->type = 0;
  435                 pa->protocol = 0;
  436                 DPRINTF(("getparm(type %d?)\n", so->so_type));
  437                 return;
  438         }
  439 }
  440 
  441 
  442 static int
  443 si_ogetudata(struct file *fp, int fd, struct svr4_strioctl *ioc,
  444     struct lwp *l)
  445 {
  446         int error;
  447         struct svr4_si_oudata ud;
  448         struct svr4_si_sockparms pa;
  449         (void)memset(&pa, 0, sizeof(pa));       /* XXX: GCC */
  450 
  451         if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) {
  452                 DPRINTF(("SI_OGETUDATA: Wrong size %ld != %d\n",
  453                     (unsigned long)sizeof(ud), ioc->len));
  454                 return EINVAL;
  455         }
  456 
  457         if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0)
  458                 return error;
  459 
  460         getparm(fp, &pa);
  461 
  462         switch (pa.family) {
  463         case AF_INET:
  464             ud.tidusize = 16384;
  465             ud.addrsize = sizeof(struct sockaddr_in);
  466             if (pa.type == SVR4_SOCK_STREAM)
  467                     ud.etsdusize = 1;
  468             else
  469                     ud.etsdusize = 0;
  470             break;
  471 
  472         case AF_LOCAL:
  473             ud.tidusize = 65536;
  474             ud.addrsize = 128;
  475             ud.etsdusize = 128;
  476             break;
  477 
  478         default:
  479             DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
  480                      pa.family));
  481             return ENOSYS;
  482         }
  483 
  484         /* I have no idea what these should be! */
  485         ud.optsize = 128;
  486         ud.tsdusize = 128;
  487 
  488         ud.servtype = pa.type;
  489 
  490         /* XXX: Fixme */
  491         ud.so_state = 0;
  492         ud.so_options = 0;
  493         return copyout(&ud, ioc->buf, ioc->len);
  494 }
  495 
  496 
  497 static int
  498 si_sockparams(struct file *fp, int fd, struct svr4_strioctl *ioc,
  499     struct lwp *l)
  500 {
  501         struct svr4_si_sockparms pa;
  502 
  503         getparm(fp, &pa);
  504         return copyout(&pa, ioc->buf, sizeof(pa));
  505 }
  506 
  507 
  508 static int
  509 si_listen(fp, fd, ioc, l)
  510         struct file             *fp;
  511         int                      fd;
  512         struct svr4_strioctl    *ioc;
  513         struct lwp              *l;
  514 {
  515         int error;
  516         struct svr4_strm *st = svr4_stream_get(fp);
  517         register_t retval;
  518         struct svr4_strmcmd lst;
  519         struct sys_listen_args la;
  520 
  521         if (st == NULL)
  522                 return EINVAL;
  523 
  524         if (ioc->len > sizeof(lst))
  525                 return EINVAL;
  526 
  527         if ((error = copyin(ioc->buf, &lst, ioc->len)) != 0)
  528                 return error;
  529 
  530         if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
  531                 DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
  532                 return EINVAL;
  533         }
  534 
  535         /*
  536          * We are making assumptions again...
  537          */
  538         SCARG(&la, s) = fd;
  539         DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5));
  540         SCARG(&la, backlog) = 5;
  541 
  542         if ((error = sys_listen(l, &la, &retval)) != 0) {
  543                 DPRINTF(("SI_LISTEN: listen failed %d\n", error));
  544                 return error;
  545         }
  546 
  547         st->s_cmd = SVR4_TI__ACCEPT_WAIT;
  548         lst.cmd = SVR4_TI_BIND_REPLY;
  549 
  550         switch (st->s_family) {
  551         case AF_INET:
  552                 /* XXX: Fill the length here */
  553                 break;
  554 
  555         case AF_LOCAL:
  556                 lst.len = 140;
  557                 lst.pad[28] = 0x00000000;       /* magic again */
  558                 lst.pad[29] = 0x00000800;       /* magic again */
  559                 lst.pad[30] = 0x80001400;       /* magic again */
  560                 break;
  561 
  562         default:
  563                 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
  564                     st->s_family));
  565                 return ENOSYS;
  566         }
  567 
  568 
  569         if ((error = copyout(&lst, ioc->buf, ioc->len)) != 0)
  570                 return error;
  571 
  572         return 0;
  573 }
  574 
  575 
  576 static int
  577 si_getudata(struct file *fp, int fd, struct svr4_strioctl *ioc,
  578     struct lwp *l)
  579 {
  580         int error;
  581         struct svr4_si_udata ud;
  582 
  583         if (sizeof(ud) != ioc->len) {
  584                 DPRINTF(("SI_GETUDATA: Wrong size %ld != %d\n",
  585                     (unsigned long)sizeof(ud), ioc->len));
  586                 return EINVAL;
  587         }
  588 
  589         if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0)
  590                 return error;
  591 
  592         getparm(fp, &ud.sockparms);
  593 
  594         switch (ud.sockparms.family) {
  595         case AF_INET:
  596             ud.tidusize = 16384;
  597             ud.tsdusize = 16384;
  598             ud.addrsize = sizeof(struct sockaddr_in);
  599             if (ud.sockparms.type == SVR4_SOCK_STREAM)
  600                     ud.etsdusize = 1;
  601             else
  602                     ud.etsdusize = 0;
  603             ud.optsize = 0;
  604             break;
  605 
  606         case AF_LOCAL:
  607             ud.tidusize = 65536;
  608             ud.tsdusize = 128;
  609             ud.addrsize = 128;
  610             ud.etsdusize = 128;
  611             ud.optsize = 128;
  612             break;
  613 
  614         default:
  615             DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
  616                      ud.sockparms.family));
  617             return ENOSYS;
  618         }
  619 
  620 
  621         ud.servtype = ud.sockparms.type;
  622 
  623         /* XXX: Fixme */
  624         ud.so_state = 0;
  625         ud.so_options = 0;
  626         return copyout(&ud, ioc->buf, sizeof(ud));
  627 }
  628 
  629 
  630 static int
  631 si_shutdown(struct file *fp, int fd, struct svr4_strioctl *ioc,
  632     struct lwp *l)
  633 {
  634         int error;
  635         struct sys_shutdown_args ap;
  636         register_t retval;
  637 
  638         if (ioc->len != sizeof(SCARG(&ap, how))) {
  639                 DPRINTF(("SI_SHUTDOWN: Wrong size %ld != %d\n",
  640                     (unsigned long)sizeof(SCARG(&ap, how)), ioc->len));
  641                 return EINVAL;
  642         }
  643 
  644         if ((error = copyin(ioc->buf, &SCARG(&ap, how), ioc->len)) != 0)
  645                 return error;
  646 
  647         SCARG(&ap, s) = fd;
  648 
  649         return sys_shutdown(l, &ap, &retval);
  650 }
  651 
  652 
  653 static int
  654 sockmod(fp, fd, ioc, l)
  655         struct file             *fp;
  656         int                      fd;
  657         struct svr4_strioctl    *ioc;
  658         struct lwp              *l;
  659 {
  660         switch (ioc->cmd) {
  661         case SVR4_SI_OGETUDATA:
  662                 DPRINTF(("SI_OGETUDATA\n"));
  663                 return si_ogetudata(fp, fd, ioc, l);
  664 
  665         case SVR4_SI_SHUTDOWN:
  666                 DPRINTF(("SI_SHUTDOWN\n"));
  667                 return si_shutdown(fp, fd, ioc, l);
  668 
  669         case SVR4_SI_LISTEN:
  670                 DPRINTF(("SI_LISTEN\n"));
  671                 return si_listen(fp, fd, ioc, l);
  672 
  673         case SVR4_SI_SETMYNAME:
  674                 DPRINTF(("SI_SETMYNAME\n"));
  675                 return 0;
  676 
  677         case SVR4_SI_SETPEERNAME:
  678                 DPRINTF(("SI_SETPEERNAME\n"));
  679                 return 0;
  680 
  681         case SVR4_SI_GETINTRANSIT:
  682                 DPRINTF(("SI_GETINTRANSIT\n"));
  683                 return 0;
  684 
  685         case SVR4_SI_TCL_LINK:
  686                 DPRINTF(("SI_TCL_LINK\n"));
  687                 return 0;
  688 
  689         case SVR4_SI_TCL_UNLINK:
  690                 DPRINTF(("SI_TCL_UNLINK\n"));
  691                 return 0;
  692 
  693         case SVR4_SI_SOCKPARAMS:
  694                 DPRINTF(("SI_SOCKPARAMS\n"));
  695                 return si_sockparams(fp, fd, ioc, l);
  696 
  697         case SVR4_SI_GETUDATA:
  698                 DPRINTF(("SI_GETUDATA\n"));
  699                 return si_getudata(fp, fd, ioc, l);
  700 
  701         default:
  702                 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd));
  703                 return 0;
  704 
  705         }
  706 }
  707 
  708 
  709 static int
  710 ti_getinfo(struct file *fp, int fd, struct svr4_strioctl *ioc,
  711     struct lwp *l)
  712 {
  713         int error;
  714         struct svr4_infocmd info;
  715 
  716         memset(&info, 0, sizeof(info));
  717 
  718         if (ioc->len > sizeof(info))
  719                 return EINVAL;
  720 
  721         if ((error = copyin(ioc->buf, &info, ioc->len)) != 0)
  722                 return error;
  723 
  724         if (info.cmd != SVR4_TI_INFO_REQUEST)
  725                 return EINVAL;
  726 
  727         info.cmd = SVR4_TI_INFO_REPLY;
  728         info.tsdu = 0;
  729         info.etsdu = 1;
  730         info.cdata = -2;
  731         info.ddata = -2;
  732         info.addr = 16;
  733         info.opt = -1;
  734         info.tidu = 16384;
  735         info.serv = 2;
  736         info.current = 0;
  737         info.provider = 2;
  738 
  739         ioc->len = sizeof(info);
  740         if ((error = copyout(&info, ioc->buf, ioc->len)) != 0)
  741                 return error;
  742 
  743         return 0;
  744 }
  745 
  746 
  747 static int
  748 ti_bind(fp, fd, ioc, l)
  749         struct file             *fp;
  750         int                      fd;
  751         struct svr4_strioctl    *ioc;
  752         struct lwp              *l;
  753 {
  754         struct proc *p = l->l_proc;
  755         int error;
  756         struct svr4_strm *st = svr4_stream_get(fp);
  757         struct sockaddr_in sain;
  758         struct sockaddr_un saun;
  759         register_t retval;
  760         caddr_t sg;
  761         void *skp, *sup = NULL;
  762         int sasize;
  763         struct svr4_strmcmd bnd;
  764         struct sys_bind_args ba;
  765 
  766         if (st == NULL) {
  767                 DPRINTF(("ti_bind: bad file descriptor\n"));
  768                 return EINVAL;
  769         }
  770 
  771         if (ioc->len > sizeof(bnd))
  772                 return EINVAL;
  773 
  774         if ((error = copyin(ioc->buf, &bnd, ioc->len)) != 0)
  775                 return error;
  776 
  777         if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) {
  778                 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
  779                 return EINVAL;
  780         }
  781 
  782         switch (st->s_family) {
  783         case AF_INET:
  784                 skp = &sain;
  785                 sasize = sizeof(sain);
  786 
  787                 if (bnd.offs == 0)
  788                         goto reply;
  789 
  790                 netaddr_to_sockaddr_in(&sain, &bnd);
  791 
  792                 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
  793                          sain.sin_family, sain.sin_port,
  794                          sain.sin_addr.s_addr));
  795                 break;
  796 
  797         case AF_LOCAL:
  798                 skp = &saun;
  799                 sasize = sizeof(saun);
  800                 if (bnd.offs == 0)
  801                         goto reply;
  802 
  803                 netaddr_to_sockaddr_un(&saun, &bnd);
  804 
  805                 if (saun.sun_path[0] == '\0')
  806                         goto reply;
  807 
  808                 DPRINTF(("TI_BIND: fam %d, path %s\n",
  809                          saun.sun_family, saun.sun_path));
  810 
  811                 if ((error = clean_pipe(l, saun.sun_path)) != 0)
  812                         return error;
  813 
  814                 bnd.pad[28] = 0x00001000;       /* magic again */
  815                 break;
  816 
  817         default:
  818                 DPRINTF(("TI_BIND: Unsupported address family %d\n",
  819                          st->s_family));
  820                 return ENOSYS;
  821         }
  822 
  823         sg = stackgap_init(p, 0);
  824         sup = stackgap_alloc(p, &sg, sasize);
  825 
  826         if ((error = copyout(skp, sup, sasize)) != 0)
  827                 return error;
  828 
  829         SCARG(&ba, s) = fd;
  830         DPRINTF(("TI_BIND: fileno %d\n", fd));
  831         SCARG(&ba, name) = (void *) sup;
  832         SCARG(&ba, namelen) = sasize;
  833 
  834         if ((error = sys_bind(l, &ba, &retval)) != 0) {
  835                 DPRINTF(("TI_BIND: bind failed %d\n", error));
  836                 return error;
  837         }
  838 
  839 reply:
  840         if (sup == NULL) {
  841                 memset(&bnd, 0, sizeof(bnd));
  842                 bnd.len = sasize + 4;
  843                 bnd.offs = 0x10;        /* XXX */
  844         }
  845 
  846         bnd.cmd = SVR4_TI_BIND_REPLY;
  847 
  848         if ((error = copyout(&bnd, ioc->buf, ioc->len)) != 0)
  849                 return error;
  850 
  851         return 0;
  852 }
  853 
  854 
  855 static int
  856 timod(fp, fd, ioc, l)
  857         struct file             *fp;
  858         int                      fd;
  859         struct svr4_strioctl    *ioc;
  860         struct lwp              *l;
  861 {
  862         switch (ioc->cmd) {
  863         case SVR4_TI_GETINFO:
  864                 DPRINTF(("TI_GETINFO\n"));
  865                 return ti_getinfo(fp, fd, ioc, l);
  866 
  867         case SVR4_TI_OPTMGMT:
  868                 DPRINTF(("TI_OPTMGMT\n"));
  869                 return 0;
  870 
  871         case SVR4_TI_BIND:
  872                 DPRINTF(("TI_BIND\n"));
  873                 return ti_bind(fp, fd, ioc, l);
  874 
  875         case SVR4_TI_UNBIND:
  876                 DPRINTF(("TI_UNBIND\n"));
  877                 return 0;
  878 
  879         default:
  880                 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd));
  881                 return 0;
  882         }
  883 }
  884 
  885 
  886 int
  887 svr4_stream_ti_ioctl(fp, l, retval, fd, cmd, dat)
  888         struct file *fp;
  889         struct lwp *l;
  890         register_t *retval;
  891         int fd;
  892         u_long cmd;
  893         caddr_t dat;
  894 {
  895         struct proc *p = l->l_proc;
  896         struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat;
  897         struct svr4_strm *st = svr4_stream_get(fp);
  898         int error;
  899         void *skp, *sup;
  900         struct sockaddr_in sain;
  901         struct sockaddr_un saun;
  902         struct svr4_strmcmd sc;
  903         int sasize;
  904         caddr_t sg;
  905         int *lenp;
  906 
  907         if (st == NULL)
  908                 return EINVAL;
  909 
  910         sc.offs = 0x10;
  911 
  912         if ((error = copyin(sub, &skb, sizeof(skb))) != 0) {
  913                 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
  914                 return error;
  915         }
  916 
  917         switch (st->s_family) {
  918         case AF_INET:
  919                 skp = &sain;
  920                 sasize = sizeof(sain);
  921                 break;
  922 
  923         case AF_LOCAL:
  924                 skp = &saun;
  925                 sasize = sizeof(saun);
  926                 break;
  927 
  928         default:
  929                 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
  930                          st->s_family));
  931                 return ENOSYS;
  932         }
  933 
  934         sg = stackgap_init(p, 0);
  935         sup = stackgap_alloc(p, &sg, sasize);
  936         lenp = stackgap_alloc(p, &sg, sizeof(*lenp));
  937 
  938         if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) {
  939                 DPRINTF(("ti_ioctl: error copying out lenp\n"));
  940                 return error;
  941         }
  942 
  943         switch (cmd) {
  944         case SVR4_TI_GETMYNAME:
  945                 DPRINTF(("TI_GETMYNAME\n"));
  946                 {
  947                         struct sys_getsockname_args ap;
  948                         SCARG(&ap, fdes) = fd;
  949                         SCARG(&ap, asa) = sup;
  950                         SCARG(&ap, alen) = (socklen_t *)lenp;
  951 
  952                         if ((error = sys_getsockname(l, &ap, retval)) != 0) {
  953                                 DPRINTF(("ti_ioctl: getsockname error\n"));
  954                                 return error;
  955                         }
  956                 }
  957                 break;
  958 
  959         case SVR4_TI_GETPEERNAME:
  960                 DPRINTF(("TI_GETPEERNAME\n"));
  961                 {
  962                         struct sys_getpeername_args ap;
  963                         SCARG(&ap, fdes) = fd;
  964                         SCARG(&ap, asa) = sup;
  965                         SCARG(&ap, alen) = (socklen_t *)lenp;
  966 
  967                         if ((error = sys_getpeername(l, &ap, retval)) != 0) {
  968                                 DPRINTF(("ti_ioctl: getpeername error\n"));
  969                                 return error;
  970                         }
  971                 }
  972                 break;
  973 
  974         case SVR4_TI_SETMYNAME:
  975                 DPRINTF(("TI_SETMYNAME\n"));
  976                 return 0;
  977 
  978         case SVR4_TI_SETPEERNAME:
  979                 DPRINTF(("TI_SETPEERNAME\n"));
  980                 return 0;
  981         default:
  982                 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd));
  983                 return ENOSYS;
  984         }
  985 
  986         if ((error = copyin(sup, skp, sasize)) != 0) {
  987                 DPRINTF(("ti_ioctl: error copying in socket data\n"));
  988                 return error;
  989         }
  990 
  991         if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) {
  992                 DPRINTF(("ti_ioctl: error copying in socket size\n"));
  993                 return error;
  994         }
  995 
  996         switch (st->s_family) {
  997         case AF_INET:
  998                 sockaddr_to_netaddr_in(&sc, &sain);
  999                 skb.len = sasize;
 1000                 break;
 1001 
 1002         case AF_LOCAL:
 1003                 sockaddr_to_netaddr_un(&sc, &saun);
 1004                 skb.len = sasize + 4;
 1005                 break;
 1006 
 1007         default:
 1008                 return ENOSYS;
 1009         }
 1010 
 1011 
 1012         if ((error = copyout(SVR4_ADDROF(&sc), skb.buf, sasize)) != 0) {
 1013                 DPRINTF(("ti_ioctl: error copying out socket data\n"));
 1014                 return error;
 1015         }
 1016 
 1017 
 1018         if ((error = copyout(&skb, sub, sizeof(skb))) != 0) {
 1019                 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
 1020                 return error;
 1021         }
 1022 
 1023         return error;
 1024 }
 1025 
 1026 
 1027 
 1028 
 1029 static int
 1030 i_nread(struct file *fp, struct lwp *l, register_t *retval, int fd,
 1031     u_long cmd, caddr_t dat)
 1032 {
 1033         int error;
 1034         int nread = 0;
 1035 
 1036         /*
 1037          * We are supposed to return the message length in nread, and the
 1038          * number of messages in retval. We don't have the notion of number
 1039          * of stream messages, so we just find out if we have any bytes waiting
 1040          * for us, and if we do, then we assume that we have at least one
 1041          * message waiting for us.
 1042          */
 1043         if ((error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD,
 1044             (caddr_t) &nread, l)) != 0)
 1045                 return error;
 1046 
 1047         if (nread != 0)
 1048                 *retval = 1;
 1049         else
 1050                 *retval = 0;
 1051 
 1052         return copyout(&nread, dat, sizeof(nread));
 1053 }
 1054 
 1055 static int
 1056 i_fdinsert(struct file *fp, struct lwp *l, register_t *retval, int fd,
 1057     u_long cmd, caddr_t dat)
 1058 {
 1059         /*
 1060          * Major hack again here. We assume that we are using this to
 1061          * implement accept(2). If that is the case, we have already
 1062          * called accept, and we have stored the file descriptor in
 1063          * afd. We find the file descriptor that the code wants to use
 1064          * in fd insert, and then we dup2() our accepted file descriptor
 1065          * to it.
 1066          */
 1067         int error;
 1068         struct svr4_strm *st = svr4_stream_get(fp);
 1069         struct svr4_strfdinsert fdi;
 1070         struct sys_dup2_args d2p;
 1071         struct sys_close_args clp;
 1072 
 1073         if (st == NULL) {
 1074                 DPRINTF(("fdinsert: bad file type\n"));
 1075                 return EINVAL;
 1076         }
 1077 
 1078         if (st->s_afd == -1) {
 1079                 DPRINTF(("fdinsert: accept fd not found\n"));
 1080                 return ENOENT;
 1081         }
 1082 
 1083         if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
 1084                 DPRINTF(("fdinsert: copyin failed %d\n", error));
 1085                 return error;
 1086         }
 1087 
 1088         SCARG(&d2p, from) = st->s_afd;
 1089         SCARG(&d2p, to) = fdi.fd;
 1090 
 1091         if ((error = sys_dup2(l, &d2p, retval)) != 0) {
 1092                 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n",
 1093                     st->s_afd, fdi.fd, error));
 1094                 return error;
 1095         }
 1096 
 1097         SCARG(&clp, fd) = st->s_afd;
 1098 
 1099         if ((error = sys_close(l, &clp, retval)) != 0) {
 1100                 DPRINTF(("fdinsert: close(%d) failed %d\n",
 1101                     st->s_afd, error));
 1102                 return error;
 1103         }
 1104 
 1105         st->s_afd = -1;
 1106 
 1107         *retval = 0;
 1108         return 0;
 1109 }
 1110 
 1111 
 1112 static int
 1113 _i_bind_rsvd(struct file *fp, struct lwp *l, register_t *retval,
 1114     int fd, u_long cmd, caddr_t dat)
 1115 {
 1116         struct sys_mknod_args ap;
 1117 
 1118         /*
 1119          * This is a supposed to be a kernel and library only ioctl.
 1120          * It gets called before ti_bind, when we have a unix
 1121          * socket, to physically create the socket transport and
 1122          * ``reserve'' it. I don't know how this get reserved inside
 1123          * the kernel, but we are going to create it nevertheless.
 1124          */
 1125         SCARG(&ap, path) = dat;
 1126         SCARG(&ap, mode) = S_IFIFO;
 1127 
 1128         return sys_mkfifo(l, &ap, retval);
 1129 }
 1130 
 1131 static int
 1132 _i_rele_rsvd(struct file *fp, struct lwp *l, register_t *retval,
 1133     int fd, u_long cmd, caddr_t dat)
 1134 {
 1135         struct sys_unlink_args ap;
 1136 
 1137         /*
 1138          * This is a supposed to be a kernel and library only ioctl.
 1139          * I guess it is supposed to release the socket.
 1140          */
 1141         SCARG(&ap, path) = dat;
 1142 
 1143         return sys_unlink(l, &ap, retval);
 1144 }
 1145 
 1146 static int
 1147 i_str(struct file *fp, struct lwp *l, register_t *retval, int fd,
 1148     u_long cmd, caddr_t dat)
 1149 {
 1150         int                      error;
 1151         struct svr4_strioctl     ioc;
 1152 
 1153         /*
 1154          * Noop on non sockets
 1155          */
 1156         if (fp->f_type != DTYPE_SOCKET)
 1157                 return 0;
 1158 
 1159         if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0)
 1160                 return error;
 1161 
 1162 #ifdef DEBUG_SVR4
 1163         if ((error = show_ioc(">", &ioc)) != 0)
 1164                 return error;
 1165 #endif /* DEBUG_SVR4 */
 1166 
 1167         switch (ioc.cmd & 0xff00) {
 1168         case SVR4_SIMOD:
 1169                 if ((error = sockmod(fp, fd, &ioc, l)) != 0)
 1170                         return error;
 1171                 break;
 1172 
 1173         case SVR4_TIMOD:
 1174                 if ((error = timod(fp, fd, &ioc, l)) != 0)
 1175                         return error;
 1176                 break;
 1177 
 1178         default:
 1179                 DPRINTF(("Unimplemented module %c %ld\n",
 1180                          (char) (cmd >> 8), cmd & 0xff));
 1181                 return 0;
 1182         }
 1183 
 1184 #ifdef DEBUG_SVR4
 1185         if ((error = show_ioc("<", &ioc)) != 0)
 1186                 return error;
 1187 #endif /* DEBUG_SVR4 */
 1188         return copyout(&ioc, dat, sizeof(ioc));
 1189 }
 1190 
 1191 static int
 1192 i_setsig(struct file *fp, struct lwp *l, register_t *retval, int fd,
 1193     u_long cmd, caddr_t dat)
 1194 {
 1195         /*
 1196          * This is the best we can do for now; we cannot generate
 1197          * signals only for specific events so the signal mask gets
 1198          * ignored; we save it just to pass it to a possible I_GETSIG...
 1199          *
 1200          * We alse have to fix the O_ASYNC fcntl bit, so the
 1201          * process will get SIGPOLLs.
 1202          */
 1203         struct sys_fcntl_args fa;
 1204         int error;
 1205         register_t oflags, flags;
 1206         struct svr4_strm *st = svr4_stream_get(fp);
 1207 
 1208         if (st == NULL) {
 1209                 DPRINTF(("i_setsig: bad file descriptor\n"));
 1210                 return EINVAL;
 1211         }
 1212         /* get old status flags */
 1213         SCARG(&fa, fd) = fd;
 1214         SCARG(&fa, cmd) = F_GETFL;
 1215 
 1216         if ((error = sys_fcntl(l, &fa, &oflags)) != 0)
 1217                 return error;
 1218 
 1219         /* update the flags */
 1220         if (dat != NULL) {
 1221                 int mask;
 1222 
 1223                 flags = oflags | O_ASYNC;
 1224                 mask = (int)(u_long)dat;
 1225                 if (mask & ~SVR4_S_ALLMASK) {
 1226                         DPRINTF(("i_setsig: bad eventmask data %x\n", mask));
 1227                         return EINVAL;
 1228                 }
 1229                 st->s_eventmask = mask;
 1230         }
 1231         else {
 1232                 flags = oflags & ~O_ASYNC;
 1233                 st->s_eventmask = 0;
 1234         }
 1235 
 1236         /* set the new flags, if changed */
 1237         if (flags != oflags) {
 1238                 SCARG(&fa, cmd) = F_SETFL;
 1239                 SCARG(&fa, arg) = (void *) flags;
 1240                 if ((error = sys_fcntl(l, &fa, &flags)) != 0)
 1241                         return error;
 1242         }
 1243 
 1244         /* set up SIGIO receiver if needed */
 1245         if (dat != NULL) {
 1246                 SCARG(&fa, cmd) = F_SETOWN;
 1247                 SCARG(&fa, arg) = (void *)(u_long)l->l_proc->p_pid;
 1248                 return sys_fcntl(l, &fa, &flags);
 1249         }
 1250         return 0;
 1251 }
 1252 
 1253 static int
 1254 i_getsig(struct file *fp, struct lwp *l, register_t *retval,
 1255     int fd, u_long cmd, caddr_t dat)
 1256 {
 1257         int error;
 1258 
 1259         if (dat != NULL) {
 1260                 struct svr4_strm *st = svr4_stream_get(fp);
 1261 
 1262                 if (st == NULL) {
 1263                         DPRINTF(("i_getsig: bad file descriptor\n"));
 1264                         return EINVAL;
 1265                 }
 1266                 if ((error = copyout(&st->s_eventmask, dat,
 1267                     sizeof(st->s_eventmask))) != 0) {
 1268                         DPRINTF(("i_getsig: bad eventmask pointer\n"));
 1269                         return error;
 1270                 }
 1271         }
 1272         return 0;
 1273 }
 1274 
 1275 int
 1276 svr4_stream_ioctl(fp, l, retval, fd, cmd, dat)
 1277         struct file *fp;
 1278         struct lwp *l;
 1279         register_t *retval;
 1280         int fd;
 1281         u_long cmd;
 1282         caddr_t dat;
 1283 {
 1284         *retval = 0;
 1285 
 1286         /*
 1287          * All the following stuff assumes "sockmod" is pushed...
 1288          */
 1289         switch (cmd) {
 1290         case SVR4_I_NREAD:
 1291                 DPRINTF(("I_NREAD\n"));
 1292                 return i_nread(fp, l, retval, fd, cmd, dat);
 1293 
 1294         case SVR4_I_PUSH:
 1295                 DPRINTF(("I_PUSH\n"));
 1296                 return 0;
 1297 
 1298         case SVR4_I_POP:
 1299                 DPRINTF(("I_POP\n"));
 1300                 return 0;
 1301 
 1302         case SVR4_I_LOOK:
 1303                 DPRINTF(("I_LOOK\n"));
 1304                 return 0;
 1305 
 1306         case SVR4_I_FLUSH:
 1307                 DPRINTF(("I_FLUSH\n"));
 1308                 return 0;
 1309 
 1310         case SVR4_I_SRDOPT:
 1311                 DPRINTF(("I_SRDOPT\n"));
 1312                 return 0;
 1313 
 1314         case SVR4_I_GRDOPT:
 1315                 DPRINTF(("I_GRDOPT\n"));
 1316                 return 0;
 1317 
 1318         case SVR4_I_STR:
 1319                 DPRINTF(("I_STR\n"));
 1320                 return i_str(fp, l, retval, fd, cmd, dat);
 1321 
 1322         case SVR4_I_SETSIG:
 1323                 DPRINTF(("I_SETSIG\n"));
 1324                 return i_setsig(fp, l, retval, fd, cmd, dat);
 1325 
 1326         case SVR4_I_GETSIG:
 1327                 DPRINTF(("I_GETSIG\n"));
 1328                 return i_getsig(fp, l, retval, fd, cmd, dat);
 1329 
 1330         case SVR4_I_FIND:
 1331                 DPRINTF(("I_FIND\n"));
 1332                 /*
 1333                  * Here we are not pushing modules really, we just
 1334                  * pretend all are present
 1335                  */
 1336                 *retval = 1;
 1337                 return 0;
 1338 
 1339         case SVR4_I_LINK:
 1340                 DPRINTF(("I_LINK\n"));
 1341                 return 0;
 1342 
 1343         case SVR4_I_UNLINK:
 1344                 DPRINTF(("I_UNLINK\n"));
 1345                 return 0;
 1346 
 1347         case SVR4_I_ERECVFD:
 1348                 DPRINTF(("I_ERECVFD\n"));
 1349                 return 0;
 1350 
 1351         case SVR4_I_PEEK:
 1352                 DPRINTF(("I_PEEK\n"));
 1353                 return 0;
 1354 
 1355         case SVR4_I_FDINSERT:
 1356                 DPRINTF(("I_FDINSERT\n"));
 1357                 return i_fdinsert(fp, l, retval, fd, cmd, dat);
 1358 
 1359         case SVR4_I_SENDFD:
 1360                 DPRINTF(("I_SENDFD\n"));
 1361                 return 0;
 1362 
 1363         case SVR4_I_RECVFD:
 1364                 DPRINTF(("I_RECVFD\n"));
 1365                 return 0;
 1366 
 1367         case SVR4_I_SWROPT:
 1368                 DPRINTF(("I_SWROPT\n"));
 1369                 return 0;
 1370 
 1371         case SVR4_I_GWROPT:
 1372                 DPRINTF(("I_GWROPT\n"));
 1373                 return 0;
 1374 
 1375         case SVR4_I_LIST:
 1376                 DPRINTF(("I_LIST\n"));
 1377                 return 0;
 1378 
 1379         case SVR4_I_PLINK:
 1380                 DPRINTF(("I_PLINK\n"));
 1381                 return 0;
 1382 
 1383         case SVR4_I_PUNLINK:
 1384                 DPRINTF(("I_PUNLINK\n"));
 1385                 return 0;
 1386 
 1387         case SVR4_I_SETEV:
 1388                 DPRINTF(("I_SETEV\n"));
 1389                 return 0;
 1390 
 1391         case SVR4_I_GETEV:
 1392                 DPRINTF(("I_GETEV\n"));
 1393                 return 0;
 1394 
 1395         case SVR4_I_STREV:
 1396                 DPRINTF(("I_STREV\n"));
 1397                 return 0;
 1398 
 1399         case SVR4_I_UNSTREV:
 1400                 DPRINTF(("I_UNSTREV\n"));
 1401                 return 0;
 1402 
 1403         case SVR4_I_FLUSHBAND:
 1404                 DPRINTF(("I_FLUSHBAND\n"));
 1405                 return 0;
 1406 
 1407         case SVR4_I_CKBAND:
 1408                 DPRINTF(("I_CKBAND\n"));
 1409                 return 0;
 1410 
 1411         case SVR4_I_GETBAND:
 1412                 DPRINTF(("I_GETBANK\n"));
 1413                 return 0;
 1414 
 1415         case SVR4_I_ATMARK:
 1416                 DPRINTF(("I_ATMARK\n"));
 1417                 return 0;
 1418 
 1419         case SVR4_I_SETCLTIME:
 1420                 DPRINTF(("I_SETCLTIME\n"));
 1421                 return 0;
 1422 
 1423         case SVR4_I_GETCLTIME:
 1424                 DPRINTF(("I_GETCLTIME\n"));
 1425                 return 0;
 1426 
 1427         case SVR4_I_CANPUT:
 1428                 DPRINTF(("I_CANPUT\n"));
 1429                 return 0;
 1430 
 1431         case SVR4__I_BIND_RSVD:
 1432                 DPRINTF(("_I_BIND_RSVD\n"));
 1433                 return _i_bind_rsvd(fp, l, retval, fd, cmd, dat);
 1434 
 1435         case SVR4__I_RELE_RSVD:
 1436                 DPRINTF(("_I_RELE_RSVD\n"));
 1437                 return _i_rele_rsvd(fp, l, retval, fd, cmd, dat);
 1438 
 1439         default:
 1440                 DPRINTF(("unimpl cmd = %lx\n", cmd));
 1441                 break;
 1442         }
 1443 
 1444         return 0;
 1445 }
 1446 
 1447 
 1448 
 1449 
 1450 int
 1451 svr4_sys_putmsg(l, v, retval)
 1452         struct lwp *l;
 1453         void *v;
 1454         register_t *retval;
 1455 {
 1456         struct svr4_sys_putmsg_args *uap = v;
 1457         struct proc *p = l->l_proc;
 1458         struct filedesc *fdp = p->p_fd;
 1459         struct file     *fp;
 1460         struct svr4_strbuf dat, ctl;
 1461         struct svr4_strmcmd sc;
 1462         struct sockaddr_in sain;
 1463         struct sockaddr_un saun;
 1464         void *skp, *sup;
 1465         int sasize;
 1466         struct svr4_strm *st;
 1467         int error;
 1468         caddr_t sg;
 1469 
 1470 #ifdef DEBUG_SVR4
 1471         show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1472                  SCARG(uap, dat), SCARG(uap, flags));
 1473 #endif /* DEBUG_SVR4 */
 1474 
 1475         if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
 1476                 return EBADF;
 1477 
 1478         simple_unlock(&fp->f_slock);
 1479 
 1480         if (SCARG(uap, ctl) != NULL) {
 1481                 if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0)
 1482                         return error;
 1483         }
 1484         else
 1485                 ctl.len = -1;
 1486 
 1487         if (SCARG(uap, dat) != NULL) {
 1488                 if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0)
 1489                         return error;
 1490         }
 1491         else
 1492                 dat.len = -1;
 1493 
 1494         /*
 1495          * Only for sockets for now.
 1496          */
 1497         if ((st = svr4_stream_get(fp)) == NULL) {
 1498                 DPRINTF(("putmsg: bad file type\n"));
 1499                 return EINVAL;
 1500         }
 1501 
 1502         if (ctl.len > sizeof(sc)) {
 1503                 DPRINTF(("putmsg: Bad control size %ld != %d\n",
 1504                     (unsigned long)sizeof(struct svr4_strmcmd), ctl.len));
 1505                 return EINVAL;
 1506         }
 1507 
 1508         if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0)
 1509                 return error;
 1510 
 1511         switch (st->s_family) {
 1512         case AF_INET:
 1513                 if (sc.len != sizeof(sain)) {
 1514 #ifdef notyet
 1515                         if (sc.cmd == SVR4_TI_DATA_REQUEST) {
 1516                                 struct sys_write_args wa;
 1517 
 1518                                 /* Solaris seems to use sc.cmd = 3 to
 1519                                  * send "expedited" data.  telnet uses
 1520                                  * this for options processing, sending EOF,
 1521                                  * etc.  I'm sure other things use it too.
 1522                                  * I don't have any documentation
 1523                                  * on it, so I'm making a guess that this
 1524                                  * is how it works. newton@atdot.dotat.org XXX
 1525                                  *
 1526                                  * Hmm, expedited data seems to be sc.cmd = 4.
 1527                                  * I think 3 is normal data. (christos)
 1528                                  */
 1529                                 DPRINTF(("sending expedited data (?)\n"));
 1530                                 SCARG(&wa, fd) = SCARG(uap, fd);
 1531                                 SCARG(&wa, buf) = dat.buf;
 1532                                 SCARG(&wa, nbyte) = dat.len;
 1533                                 return sys_write(l, &wa, retval);
 1534                         }
 1535 #endif
 1536                         DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len));
 1537                         return EINVAL;
 1538                 }
 1539                 netaddr_to_sockaddr_in(&sain, &sc);
 1540                 skp = &sain;
 1541                 sasize = sizeof(sain);
 1542                 error = sain.sin_family != st->s_family;
 1543                 break;
 1544 
 1545         case AF_LOCAL:
 1546                 if (ctl.len == 8) {
 1547                         /* We are doing an accept; succeed */
 1548                         DPRINTF(("putmsg: Do nothing\n"));
 1549                         *retval = 0;
 1550                         return 0;
 1551                 }
 1552                 else {
 1553                         /* Maybe we've been given a device/inode pair */
 1554                         dev_t *dev = SVR4_ADDROF(&sc);
 1555                         svr4_ino_t *ino = (svr4_ino_t *) &dev[1];
 1556                         skp = svr4_find_socket(p, fp, *dev, *ino);
 1557                         if (skp == NULL) {
 1558                                 skp = &saun;
 1559                                 /* I guess we have it by name */
 1560                                 netaddr_to_sockaddr_un(skp, &sc);
 1561                         }
 1562                         sasize = sizeof(saun);
 1563                 }
 1564                 break;
 1565 
 1566         default:
 1567                 DPRINTF(("putmsg: Unsupported address family %d\n",
 1568                          st->s_family));
 1569                 return ENOSYS;
 1570         }
 1571 
 1572         sg = stackgap_init(p, 0);
 1573         sup = stackgap_alloc(p, &sg, sasize);
 1574 
 1575         if ((error = copyout(skp, sup, sasize)) != 0)
 1576                 return error;
 1577 
 1578         switch (st->s_cmd = sc.cmd) {
 1579         case SVR4_TI_CONNECT_REQUEST:   /* connect      */
 1580                 {
 1581                         struct sys_connect_args co;
 1582 
 1583                         SCARG(&co, s) = SCARG(uap, fd);
 1584                         SCARG(&co, name) = (void *) sup;
 1585                         SCARG(&co, namelen) = (int) sasize;
 1586                         return sys_connect(l, &co, retval);
 1587                 }
 1588 
 1589         case SVR4_TI_SENDTO_REQUEST:    /* sendto       */
 1590                 {
 1591                         struct msghdr msg;
 1592                         struct iovec aiov;
 1593 
 1594                         msg.msg_name = (caddr_t) sup;
 1595                         msg.msg_namelen = sasize;
 1596                         msg.msg_iov = &aiov;
 1597                         msg.msg_iovlen = 1;
 1598                         msg.msg_control = 0;
 1599                         msg.msg_flags = 0;
 1600                         aiov.iov_base = dat.buf;
 1601                         aiov.iov_len = dat.len;
 1602                         error = sendit(l, SCARG(uap, fd), &msg,
 1603                                        SCARG(uap, flags), retval);
 1604 
 1605                         *retval = 0;
 1606                         return error;
 1607                 }
 1608 
 1609         default:
 1610                 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd));
 1611                 return ENOSYS;
 1612         }
 1613 }
 1614 
 1615 
 1616 int
 1617 svr4_sys_getmsg(l, v, retval)
 1618         struct lwp *l;
 1619         void *v;
 1620         register_t *retval;
 1621 {
 1622         struct svr4_sys_getmsg_args *uap = v;
 1623         struct proc *p = l->l_proc;
 1624         struct filedesc *fdp = p->p_fd;
 1625         struct file     *fp;
 1626         struct sys_getpeername_args ga;
 1627         struct sys_accept_args aa;
 1628         struct svr4_strbuf dat, ctl;
 1629         struct svr4_strmcmd sc;
 1630         int error;
 1631         struct msghdr msg;
 1632         struct iovec aiov;
 1633         struct sockaddr_in sain;
 1634         struct sockaddr_un saun;
 1635         void *skp, *sup;
 1636         int sasize;
 1637         struct svr4_strm *st;
 1638         int *flen;
 1639         int fl;
 1640         caddr_t sg;
 1641 
 1642         memset(&sc, 0, sizeof(sc));
 1643 
 1644 #ifdef DEBUG_SVR4
 1645         show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1646                  SCARG(uap, dat), 0);
 1647 #endif /* DEBUG_SVR4 */
 1648 
 1649         if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
 1650                 return EBADF;
 1651 
 1652         simple_unlock(&fp->f_slock);
 1653 
 1654         if (SCARG(uap, ctl) != NULL) {
 1655                 if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0)
 1656                         return error;
 1657         }
 1658         else {
 1659                 ctl.len = -1;
 1660                 ctl.maxlen = 0;
 1661         }
 1662 
 1663         if (SCARG(uap, dat) != NULL) {
 1664                 if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0)
 1665                         return error;
 1666         }
 1667         else {
 1668                 dat.len = -1;
 1669                 dat.maxlen = 0;
 1670         }
 1671 
 1672         /*
 1673          * Only for sockets for now.
 1674          */
 1675         if ((st = svr4_stream_get(fp)) == NULL) {
 1676                 DPRINTF(("getmsg: bad file type\n"));
 1677                 return EINVAL;
 1678         }
 1679 
 1680         if (ctl.maxlen == -1 || dat.maxlen == -1) {
 1681                 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
 1682                 return ENOSYS;
 1683         }
 1684 
 1685         switch (st->s_family) {
 1686         case AF_INET:
 1687                 skp = &sain;
 1688                 sasize = sizeof(sain);
 1689                 break;
 1690 
 1691         case AF_LOCAL:
 1692                 skp = &saun;
 1693                 sasize = sizeof(saun);
 1694                 break;
 1695 
 1696         default:
 1697                 DPRINTF(("getmsg: Unsupported address family %d\n",
 1698                          st->s_family));
 1699                 return ENOSYS;
 1700         }
 1701 
 1702         sg = stackgap_init(p, 0);
 1703         sup = stackgap_alloc(p, &sg, sasize);
 1704         flen = (int *) stackgap_alloc(p, &sg, sizeof(*flen));
 1705 
 1706         fl = sasize;
 1707         if ((error = copyout(&fl, flen, sizeof(fl))) != 0)
 1708                 return error;
 1709 
 1710         switch (st->s_cmd) {
 1711         case SVR4_TI_CONNECT_REQUEST:
 1712                 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
 1713                 /*
 1714                  * We do the connect in one step, so the putmsg should
 1715                  * have gotten the error.
 1716                  */
 1717                 sc.cmd = SVR4_TI_OK_REPLY;
 1718                 sc.len = 0;
 1719 
 1720                 ctl.len = 8;
 1721                 dat.len = -1;
 1722                 fl = 1;
 1723                 st->s_cmd = sc.cmd;
 1724                 break;
 1725 
 1726         case SVR4_TI_OK_REPLY:
 1727                 DPRINTF(("getmsg: TI_OK_REPLY\n"));
 1728                 /*
 1729                  * We are immediately after a connect reply, so we send
 1730                  * a connect verification.
 1731                  */
 1732 
 1733                 SCARG(&ga, fdes) = SCARG(uap, fd);
 1734                 SCARG(&ga, asa) = (void *) sup;
 1735                 SCARG(&ga, alen) = (socklen_t *)flen;
 1736 
 1737                 if ((error = sys_getpeername(l, &ga, retval)) != 0) {
 1738                         DPRINTF(("getmsg: getpeername failed %d\n", error));
 1739                         return error;
 1740                 }
 1741 
 1742                 if ((error = copyin(sup, skp, sasize)) != 0)
 1743                         return error;
 1744 
 1745                 sc.cmd = SVR4_TI_CONNECT_REPLY;
 1746                 sc.pad[0] = 0x4;
 1747                 sc.offs = 0x18;
 1748                 sc.pad[1] = 0x14;
 1749                 sc.pad[2] = 0x04000402;
 1750 
 1751                 switch (st->s_family) {
 1752                 case AF_INET:
 1753                         sc.len = sasize;
 1754                         sockaddr_to_netaddr_in(&sc, &sain);
 1755                         break;
 1756 
 1757                 case AF_LOCAL:
 1758                         sc.len = sasize + 4;
 1759                         sockaddr_to_netaddr_un(&sc, &saun);
 1760                         break;
 1761 
 1762                 default:
 1763                         return ENOSYS;
 1764                 }
 1765 
 1766                 ctl.len = 40;
 1767                 dat.len = -1;
 1768                 fl = 0;
 1769                 st->s_cmd = sc.cmd;
 1770                 break;
 1771 
 1772         case SVR4_TI__ACCEPT_OK:
 1773                 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
 1774                 /*
 1775                  * We do the connect in one step, so the putmsg should
 1776                  * have gotten the error.
 1777                  */
 1778                 sc.cmd = SVR4_TI_OK_REPLY;
 1779                 sc.len = 1;
 1780 
 1781                 ctl.len = 8;
 1782                 dat.len = -1;
 1783                 fl = 1;
 1784                 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
 1785                 break;
 1786 
 1787         case SVR4_TI__ACCEPT_WAIT:
 1788                 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
 1789                 /*
 1790                  * We are after a listen, so we try to accept...
 1791                  */
 1792                 SCARG(&aa, s) = SCARG(uap, fd);
 1793                 SCARG(&aa, name) = (void *) sup;
 1794                 SCARG(&aa, anamelen) = (socklen_t *)flen;
 1795 
 1796                 if ((error = sys_accept(l, &aa, retval)) != 0) {
 1797                         DPRINTF(("getmsg: accept failed %d\n", error));
 1798                         return error;
 1799                 }
 1800 
 1801                 st->s_afd = *retval;
 1802 
 1803                 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
 1804 
 1805                 if ((error = copyin(sup, skp, sasize)) != 0)
 1806                         return error;
 1807 
 1808                 sc.cmd = SVR4_TI_ACCEPT_REPLY;
 1809                 sc.offs = 0x18;
 1810                 sc.pad[0] = 0x0;
 1811 
 1812                 switch (st->s_family) {
 1813                 case AF_INET:
 1814                         sc.pad[1] = 0x28;
 1815                         sockaddr_to_netaddr_in(&sc, &sain);
 1816                         ctl.len = 40;
 1817                         sc.len = sasize;
 1818                         break;
 1819 
 1820                 case AF_LOCAL:
 1821                         sc.pad[1] = 0x00010000;
 1822                         sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */
 1823                         sc.pad[3] = 0x00010000;
 1824                         ctl.len = 134;
 1825                         sc.len = sasize + 4;
 1826                         break;
 1827 
 1828                 default:
 1829                         return ENOSYS;
 1830                 }
 1831 
 1832                 dat.len = -1;
 1833                 fl = 0;
 1834                 st->s_cmd = SVR4_TI__ACCEPT_OK;
 1835                 break;
 1836 
 1837         case SVR4_TI_SENDTO_REQUEST:
 1838                 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
 1839                 if (ctl.maxlen > 36 && ctl.len < 36)
 1840                     ctl.len = 36;
 1841                 if (ctl.len > sizeof(sc))
 1842                         ctl.len = sizeof(sc);
 1843 
 1844                 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0)
 1845                         return error;
 1846 
 1847                 switch (st->s_family) {
 1848                 case AF_INET:
 1849                         sockaddr_to_netaddr_in(&sc, &sain);
 1850                         break;
 1851 
 1852                 case AF_LOCAL:
 1853                         sockaddr_to_netaddr_un(&sc, &saun);
 1854                         break;
 1855 
 1856                 default:
 1857                         return ENOSYS;
 1858                 }
 1859 
 1860                 msg.msg_name = (caddr_t) sup;
 1861                 msg.msg_namelen = sasize;
 1862                 msg.msg_iov = &aiov;
 1863                 msg.msg_iovlen = 1;
 1864                 msg.msg_control = 0;
 1865                 aiov.iov_base = dat.buf;
 1866                 aiov.iov_len = dat.maxlen;
 1867                 msg.msg_flags = 0;
 1868 
 1869                 error = recvit(l, SCARG(uap, fd), &msg, (caddr_t) flen,
 1870                     retval);
 1871 
 1872                 if (error) {
 1873                         DPRINTF(("getmsg: recvit failed %d\n", error));
 1874                         return error;
 1875                 }
 1876 
 1877                 if ((error = copyin(msg.msg_name, skp, sasize)) != 0)
 1878                         return error;
 1879 
 1880                 sc.cmd = SVR4_TI_RECVFROM_IND;
 1881 
 1882                 switch (st->s_family) {
 1883                 case AF_INET:
 1884                         sc.len = sasize;
 1885                         sockaddr_to_netaddr_in(&sc, &sain);
 1886                         break;
 1887 
 1888                 case AF_LOCAL:
 1889                         sc.len = sasize + 4;
 1890                         sockaddr_to_netaddr_un(&sc, &saun);
 1891                         break;
 1892 
 1893                 default:
 1894                         return ENOSYS;
 1895                 }
 1896 
 1897                 dat.len = *retval;
 1898                 fl = 0;
 1899                 st->s_cmd = sc.cmd;
 1900                 break;
 1901 
 1902         default:
 1903                 st->s_cmd = sc.cmd;
 1904 #ifdef notyet
 1905                 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) {
 1906                         struct sys_read_args ra;
 1907 
 1908                         /* More weirdness:  Again, I can't find documentation
 1909                          * to back this up, but when a process does a generic
 1910                          * "getmsg()" call it seems that the command field is
 1911                          * zero and the length of the data area is zero.  I
 1912                          * think processes expect getmsg() to fill in dat.len
 1913                          * after reading at most dat.maxlen octets from the
 1914                          * stream.  Since we're using sockets I can let
 1915                          * read() look after it and frob return values
 1916                          * appropriately (or inappropriately :-)
 1917                          *   -- newton@atdot.dotat.org        XXX
 1918                          */
 1919                         SCARG(&ra, fd) = SCARG(uap, fd);
 1920                         SCARG(&ra, buf) = dat.buf;
 1921                         SCARG(&ra, nbyte) = dat.maxlen;
 1922                         if ((error = sys_read(p, &ra, retval)) != 0)
 1923                                 return error;
 1924                         dat.len = *retval;
 1925                         *retval = 0;
 1926                         st->s_cmd = SVR4_TI_SENDTO_REQUEST;
 1927                         break;
 1928 
 1929                 }
 1930 #endif
 1931                 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
 1932                 return EINVAL;
 1933         }
 1934 
 1935         if (SCARG(uap, ctl)) {
 1936                 if (ctl.len != -1)
 1937                         if ((error = copyout(&sc, ctl.buf, ctl.len)) != 0)
 1938                                 return error;
 1939 
 1940                 if ((error = copyout(&ctl, SCARG(uap, ctl), sizeof(ctl))) != 0)
 1941                         return error;
 1942         }
 1943 
 1944         if (SCARG(uap, dat)) {
 1945                 if ((error = copyout(&dat, SCARG(uap, dat), sizeof(dat))) != 0)
 1946                         return error;
 1947         }
 1948 
 1949         if (SCARG(uap, flags)) { /* XXX: Need translation */
 1950                 if ((error = copyout(&fl, SCARG(uap, flags), sizeof(fl))) != 0)
 1951                         return error;
 1952         }
 1953 
 1954         *retval = 0;
 1955 
 1956 #ifdef DEBUG_SVR4
 1957         show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1958                  SCARG(uap, dat), fl);
 1959 #endif /* DEBUG_SVR4 */
 1960         return error;
 1961 }

Cache object: 09db99b7b3c40c45c0caa05298428b15


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