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

Cache object: cb30a7874f901010e7d9f183f1315696


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