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_socket.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_socket.c,v 1.21 2008/06/18 02:08:36 dogcow Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 1996, 2008 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  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * In SVR4 unix domain sockets are referenced sometimes
   34  * (in putmsg(2) for example) as a [device, inode] pair instead of a pathname.
   35  * Since there is no iname() routine in the kernel, and we need access to
   36  * a mapping from inode to pathname, we keep our own table. This is a simple
   37  * linked list that contains the pathname, the [device, inode] pair, the
   38  * file corresponding to that socket and the process. When the
   39  * socket gets closed we remove the item from the list. The list gets loaded
   40  * every time a stat(2) call finds a socket.
   41  */
   42 
   43 #include <sys/cdefs.h>
   44 __KERNEL_RCSID(0, "$NetBSD: svr4_socket.c,v 1.21 2008/06/18 02:08:36 dogcow Exp $");
   45 
   46 #include <sys/param.h>
   47 #include <sys/kernel.h>
   48 #include <sys/systm.h>
   49 #include <sys/queue.h>
   50 #include <sys/mbuf.h>
   51 #include <sys/file.h>
   52 #include <sys/mount.h>
   53 #include <sys/sched.h>
   54 #include <sys/socket.h>
   55 #include <sys/socketvar.h>
   56 #include <sys/syscallargs.h>
   57 #include <sys/un.h>
   58 #include <sys/stat.h>
   59 
   60 #include <compat/svr4/svr4_types.h>
   61 #include <compat/svr4/svr4_util.h>
   62 #include <compat/svr4/svr4_socket.h>
   63 #include <compat/svr4/svr4_signal.h>
   64 #include <compat/svr4/svr4_sockmod.h>
   65 #include <compat/svr4/svr4_lwp.h>
   66 #include <compat/svr4/svr4_ucontext.h>
   67 #include <compat/svr4/svr4_syscallargs.h>
   68 
   69 struct svr4_sockcache_entry {
   70         struct proc *p;         /* Process for the socket               */
   71         void *cookie;           /* Internal cookie used for matching    */
   72         struct sockaddr_un sock;/* Pathname for the socket              */
   73         dev_t dev;              /* Device where the socket lives on     */
   74         svr4_ino_t ino;         /* Inode where the socket lives on      */
   75         TAILQ_ENTRY(svr4_sockcache_entry) entries;
   76 };
   77 
   78 static TAILQ_HEAD(svr4_sockcache_head, svr4_sockcache_entry) svr4_head;
   79 static int initialized = 0;
   80 
   81 struct sockaddr_un *
   82 svr4_find_socket(struct proc *p, struct file *fp, dev_t dev, svr4_ino_t ino)
   83 {
   84         struct svr4_sockcache_entry *e;
   85         void *cookie = ((struct socket *) fp->f_data)->so_internal;
   86 
   87         if (!initialized) {
   88                 DPRINTF(("svr4_find_socket: uninitialized [%p,%d,%lu]\n",
   89                     p, dev, ino));
   90                 TAILQ_INIT(&svr4_head);
   91                 initialized = 1;
   92                 return NULL;
   93         }
   94 
   95 
   96         DPRINTF(("svr4_find_socket: [%p,%d,%lu]: ", p, dev, ino));
   97         for (e = svr4_head.tqh_first; e != NULL; e = e->entries.tqe_next)
   98                 if (e->p == p && e->dev == dev && e->ino == ino) {
   99 #ifdef DIAGNOSTIC
  100                         if (e->cookie != NULL && e->cookie != cookie)
  101                                 panic("svr4 socket cookie mismatch");
  102 #endif
  103                         e->cookie = cookie;
  104                         DPRINTF(("%s\n", e->sock.sun_path));
  105                         return &e->sock;
  106                 }
  107 
  108         DPRINTF(("not found\n"));
  109         return NULL;
  110 }
  111 
  112 
  113 void
  114 svr4_delete_socket(struct proc *p, struct file *fp)
  115 {
  116         struct svr4_sockcache_entry *e;
  117         void *cookie = ((struct socket *) fp->f_data)->so_internal;
  118 
  119         KERNEL_LOCK(1, NULL);
  120 
  121         if (!initialized) {
  122                 TAILQ_INIT(&svr4_head);
  123                 initialized = 1;
  124                 KERNEL_UNLOCK_ONE(NULL);
  125                 return;
  126         }
  127 
  128         for (e = svr4_head.tqh_first; e != NULL; e = e->entries.tqe_next)
  129                 if (e->p == p && e->cookie == cookie) {
  130                         TAILQ_REMOVE(&svr4_head, e, entries);
  131                         DPRINTF(("svr4_delete_socket: %s [%p,%d,%lu]\n",
  132                                  e->sock.sun_path, p, e->dev, e->ino));
  133                         free(e, M_TEMP);
  134                         break;
  135                 }
  136 
  137         KERNEL_UNLOCK_ONE(NULL);
  138 }
  139 
  140 
  141 int
  142 svr4_add_socket(struct proc *p, const char *path, struct stat *st)
  143 {
  144         struct svr4_sockcache_entry *e;
  145         size_t len;
  146         int error;
  147 
  148         KERNEL_LOCK(1, NULL);
  149 
  150         if (!initialized) {
  151                 TAILQ_INIT(&svr4_head);
  152                 initialized = 1;
  153         }
  154 
  155         e = malloc(sizeof(*e), M_TEMP, M_WAITOK);
  156         e->cookie = NULL;
  157         e->dev = st->st_dev;
  158         e->ino = st->st_ino;
  159         e->p = p;
  160 
  161         if ((error = copyinstr(path, e->sock.sun_path,
  162             sizeof(e->sock.sun_path), &len)) != 0) {
  163                 DPRINTF(("svr4_add_socket: copyinstr failed %d\n", error));
  164                 free(e, M_TEMP);
  165                 KERNEL_UNLOCK_ONE(NULL);
  166                 return error;
  167         }
  168 
  169         e->sock.sun_family = AF_LOCAL;
  170         e->sock.sun_len = len;
  171 
  172         TAILQ_INSERT_HEAD(&svr4_head, e, entries);
  173         DPRINTF(("svr4_add_socket: %s [%p,%d,%lu]\n", e->sock.sun_path,
  174                  p, e->dev, e->ino));
  175 
  176         KERNEL_UNLOCK_ONE(NULL);
  177         return 0;
  178 }
  179 
  180 
  181 int
  182 svr4_sys_socket(struct lwp *l, const struct svr4_sys_socket_args *uap, register_t *retval)
  183 {
  184         struct sys___socket30_args bsd_ua;
  185 
  186         SCARG(&bsd_ua, domain) = SCARG(uap, domain);
  187         SCARG(&bsd_ua, protocol) = SCARG(uap, protocol);
  188 
  189         switch (SCARG(uap, type)) {
  190         case SVR4_SOCK_DGRAM:
  191                 SCARG(&bsd_ua, type) = SOCK_DGRAM;
  192                 break;
  193 
  194         case SVR4_SOCK_STREAM:
  195                 SCARG(&bsd_ua, type) = SOCK_STREAM;
  196                 break;
  197 
  198         case SVR4_SOCK_RAW:
  199                 SCARG(&bsd_ua, type) = SOCK_RAW;
  200                 break;
  201 
  202         case SVR4_SOCK_RDM:
  203                 SCARG(&bsd_ua, type) = SOCK_RDM;
  204                 break;
  205 
  206         case SVR4_SOCK_SEQPACKET:
  207                 SCARG(&bsd_ua, type) = SOCK_SEQPACKET;
  208                 break;
  209         default:
  210                 return EINVAL;
  211         }
  212         return sys___socket30(l, &bsd_ua, retval);
  213 }

Cache object: 5dd2e86f745231ee1859e442cebc30de


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