Annotation of sys/compat/svr4/svr4_socket.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: svr4_socket.c,v 1.5 2006/03/05 21:48:56 miod Exp $ */
! 2: /* $NetBSD: svr4_socket.c,v 1.4 1997/07/21 23:02:37 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1996 Christos Zoulas. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by Christos Zoulas.
! 18: * 4. The name of the author may not be used to endorse or promote products
! 19: * derived from this software without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 31: */
! 32:
! 33: /*
! 34: * In SVR4 unix domain sockets are referenced sometimes
! 35: * (in putmsg(2) for example) as a [device, inode] pair instead of a pathname.
! 36: * Since there is no iname() routine in the kernel, and we need access to
! 37: * a mapping from inode to pathname, we keep our own table. This is a simple
! 38: * linked list that contains the pathname, the [device, inode] pair, the
! 39: * file corresponding to that socket and the process. When the
! 40: * socket gets closed we remove the item from the list. The list gets loaded
! 41: * every time a stat(2) call finds a socket.
! 42: */
! 43:
! 44: #include <sys/param.h>
! 45: #include <sys/kernel.h>
! 46: #include <sys/systm.h>
! 47: #include <sys/queue.h>
! 48: #include <sys/mbuf.h>
! 49: #include <sys/file.h>
! 50: #include <sys/mount.h>
! 51: #include <sys/socket.h>
! 52: #include <sys/socketvar.h>
! 53: #include <sys/syscallargs.h>
! 54: #include <sys/un.h>
! 55: #include <sys/stat.h>
! 56:
! 57: #include <compat/svr4/svr4_types.h>
! 58: #include <compat/svr4/svr4_util.h>
! 59: #include <compat/svr4/svr4_socket.h>
! 60: #include <compat/svr4/svr4_signal.h>
! 61: #include <compat/svr4/svr4_sockmod.h>
! 62: #include <compat/svr4/svr4_syscallargs.h>
! 63:
! 64: struct svr4_sockcache_entry {
! 65: struct proc *p; /* Process for the socket */
! 66: void *cookie; /* Internal cookie used for matching */
! 67: struct sockaddr_un sock;/* Pathname for the socket */
! 68: dev_t dev; /* Device where the socket lives on */
! 69: ino_t ino; /* Inode where the socket lives on */
! 70: TAILQ_ENTRY(svr4_sockcache_entry) entries;
! 71: };
! 72:
! 73: static TAILQ_HEAD(svr4_sockcache_head, svr4_sockcache_entry) svr4_head;
! 74: static int initialized = 0;
! 75:
! 76: struct sockaddr_un *
! 77: svr4_find_socket(p, fp, dev, ino)
! 78: struct proc *p;
! 79: struct file *fp;
! 80: dev_t dev;
! 81: ino_t ino;
! 82: {
! 83: struct svr4_sockcache_entry *e;
! 84: void *cookie = ((struct socket *) fp->f_data)->so_internal;
! 85:
! 86: if (!initialized) {
! 87: DPRINTF(("svr4_find_socket: uninitialized [%p,%d,%d]\n",
! 88: p, dev, ino));
! 89: TAILQ_INIT(&svr4_head);
! 90: initialized = 1;
! 91: return NULL;
! 92: }
! 93:
! 94:
! 95: DPRINTF(("svr4_find_socket: [%p,%d,%d]: ", p, dev, ino));
! 96: TAILQ_FOREACH(e, &svr4_head, entries)
! 97: if (e->p == p && e->dev == dev && e->ino == ino) {
! 98: #ifdef DIAGNOSTIC
! 99: if (e->cookie != NULL && e->cookie != cookie)
! 100: panic("svr4 socket cookie mismatch");
! 101: #endif
! 102: e->cookie = cookie;
! 103: DPRINTF(("%s\n", e->sock.sun_path));
! 104: return &e->sock;
! 105: }
! 106:
! 107: DPRINTF(("not found\n"));
! 108: return NULL;
! 109: }
! 110:
! 111:
! 112: void
! 113: svr4_delete_socket(p, fp)
! 114: struct proc *p;
! 115: struct file *fp;
! 116: {
! 117: struct svr4_sockcache_entry *e;
! 118: void *cookie = ((struct socket *) fp->f_data)->so_internal;
! 119:
! 120: if (!initialized) {
! 121: TAILQ_INIT(&svr4_head);
! 122: initialized = 1;
! 123: return;
! 124: }
! 125:
! 126: TAILQ_FOREACH(e, &svr4_head, entries)
! 127: if (e->p == p && e->cookie == cookie) {
! 128: TAILQ_REMOVE(&svr4_head, e, entries);
! 129: DPRINTF(("svr4_delete_socket: %s [%p,%d,%d]\n",
! 130: e->sock.sun_path, p, e->dev, e->ino));
! 131: free(e, M_TEMP);
! 132: return;
! 133: }
! 134: }
! 135:
! 136:
! 137: int
! 138: svr4_add_socket(p, path, st)
! 139: struct proc *p;
! 140: const char *path;
! 141: struct stat *st;
! 142: {
! 143: struct svr4_sockcache_entry *e;
! 144: size_t len;
! 145: int error;
! 146:
! 147: if (!initialized) {
! 148: TAILQ_INIT(&svr4_head);
! 149: initialized = 1;
! 150: }
! 151:
! 152: e = malloc(sizeof(*e), M_TEMP, M_WAITOK);
! 153: e->cookie = NULL;
! 154: e->dev = st->st_dev;
! 155: e->ino = st->st_ino;
! 156: e->p = p;
! 157:
! 158: if ((error = copyinstr(path, e->sock.sun_path,
! 159: sizeof(e->sock.sun_path), &len)) != 0) {
! 160: DPRINTF(("svr4_add_socket: copyinstr failed %d\n", error));
! 161: free(e, M_TEMP);
! 162: return error;
! 163: }
! 164:
! 165: e->sock.sun_family = AF_UNIX;
! 166: e->sock.sun_len = len;
! 167:
! 168: TAILQ_INSERT_HEAD(&svr4_head, e, entries);
! 169: DPRINTF(("svr4_add_socket: %s [%p,%d,%d]\n", e->sock.sun_path,
! 170: p, e->dev, e->ino));
! 171: return 0;
! 172: }
! 173:
! 174:
! 175: int
! 176: svr4_sys_socket(p, v, retval)
! 177: struct proc *p;
! 178: void *v;
! 179: register_t *retval;
! 180: {
! 181: struct svr4_sys_socket_args *uap = v;
! 182:
! 183: switch (SCARG(uap, type)) {
! 184: case SVR4_SOCK_DGRAM:
! 185: SCARG(uap, type) = SOCK_DGRAM;
! 186: break;
! 187:
! 188: case SVR4_SOCK_STREAM:
! 189: SCARG(uap, type) = SOCK_STREAM;
! 190: break;
! 191:
! 192: case SVR4_SOCK_RAW:
! 193: SCARG(uap, type) = SOCK_RAW;
! 194: break;
! 195:
! 196: case SVR4_SOCK_RDM:
! 197: SCARG(uap, type) = SOCK_RDM;
! 198: break;
! 199:
! 200: case SVR4_SOCK_SEQPACKET:
! 201: SCARG(uap, type) = SOCK_SEQPACKET;
! 202: break;
! 203: default:
! 204: return EINVAL;
! 205: }
! 206: return sys_socket(p, uap, retval);
! 207: }
CVSweb