/* * NET3: Implementation of BSD Unix domain sockets. * * Authors: Alan Cox, <alan.cox@linux.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Version: $Id: af_unix.c,v 1.108 2000/11/10 04:02:04 davem Exp $ * * Fixes: * Linus Torvalds : Assorted bug cures. * Niibe Yutaka : async I/O support. * Carsten Paeth : PF_UNIX check, address fixes. * Alan Cox : Limit size of allocated blocks. * Alan Cox : Fixed the stupid socketpair bug. * Alan Cox : BSD compatibility fine tuning. * Alan Cox : Fixed a bug in connect when interrupted. * Alan Cox : Sorted out a proper draft version of * file descriptor passing hacked up from * Mike Shaver's work. * Marty Leisner : Fixes to fd passing * Nick Nevin : recvmsg bugfix. * Alan Cox : Started proper garbage collector * Heiko EiBfeldt : Missing verify_area check * Alan Cox : Started POSIXisms * Andreas Schwab : Replace inode by dentry for proper * reference counting * Kirk Petersen : Made this a module * Christoph Rohland : Elegant non-blocking accept/connect algorithm. * Lots of bug fixes. * Alexey Kuznetosv : Repaired (I hope) bugs introduces * by above two patches. * Andrea Arcangeli : If possible we block in connect(2) * if the max backlog of the listen socket * is been reached. This won't break * old apps and it will avoid huge amount * of socks hashed (this for unix_gc() * performances reasons). * Security fix that limits the max * number of socks to 2*max_files and * the number of skb queueable in the * dgram receiver. * Artur Skawina : Hash function optimizations * Alexey Kuznetsov : Full scale SMP. Lot of bugs are introduced 8) * Malcolm Beattie : Set peercred for socketpair * Michal Ostrowski : Module initialization cleanup. * * * Known differences from reference BSD that was tested: * * [TO FIX] * ECONNREFUSED is not returned from one end of a connected() socket to the * other the moment one end closes. * fstat() doesn't return st_dev=NODEV, and give the blksize as high water mark * and a fake inode identifier (nor the BSD first socket fstat twice bug). * [NOT TO FIX] * accept() returns a path name even if the connecting socket has closed * in the meantime (BSD loses the path and gives up). * accept() returns 0 length path for an unbound connector. BSD returns 16 * and a null first byte in the path (but not for gethost/peername - BSD bug ??) * socketpair(...SOCK_RAW..) doesn't panic the kernel. * BSD af_unix apparently has connect forgetting to block properly. * (need to check this with the POSIX spec in detail) * * Differences from 2.0.0-11-... (ANK) * Bug fixes and improvements. * - client shutdown killed server socket. * - removed all useless cli/sti pairs. * * Semantic changes/extensions. * - generic control message passing. * - SCM_CREDENTIALS control message. * - "Abstract" (not FS based) socket bindings. * Abstract names are sequences of bytes (not zero terminated) * started by 0, so that this name space does not intersect * with BSD names. */ #include <linux/module.h> #include <linux/config.h> #include <linux/kernel.h> #include <linux/major.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/stat.h> #include <linux/socket.h> #include <linux/un.h> #include <linux/fcntl.h> #include <linux/termios.h> #include <linux/sockios.h> #include <linux/net.h> #include <linux/in.h> #include <linux/fs.h> #include <linux/malloc.h> #include <asm/uaccess.h> #include <linux/skbuff.h> #include <linux/netdevice.h> #include <net/sock.h> #include <net/tcp.h> #include <net/af_unix.h> #include <linux/proc_fs.h> #include <net/scm.h> #include <linux/init.h> #include <linux/poll.h> #include <linux/smp_lock.h> #include <asm/checksum.h> #define min(a,b) (((a)<(b))?(a):(b)) int sysctl_unix_max_dgram_qlen = 10; unix_socket *unix_socket_table[UNIX_HASH_SIZE+1]; rwlock_t unix_table_lock = RW_LOCK_UNLOCKED; static atomic_t unix_nr_socks = ATOMIC_INIT(0); #define unix_sockets_unbound (unix_socket_table[UNIX_HASH_SIZE]) #define UNIX_ABSTRACT(sk) ((sk)->protinfo.af_unix.addr->hash!=UNIX_HASH_SIZE) /* SMP locking strategy. * hash table is protceted with rwlock unix_table_lock * each socket state is protected by separate rwlock. */ 133 extern __inline__ unsigned unix_hash_fold(unsigned hash) { hash ^= hash>>16; hash ^= hash>>8; 137 return hash&(UNIX_HASH_SIZE-1); } #define unix_peer(sk) ((sk)->pair) 142 extern __inline__ int unix_our_peer(unix_socket *sk, unix_socket *osk) { 144 return unix_peer(osk) == sk; } 147 extern __inline__ int unix_may_send(unix_socket *sk, unix_socket *osk) { 149 return (unix_peer(osk) == NULL || unix_our_peer(sk, osk)); } 152 static __inline__ unix_socket * unix_peer_get(unix_socket *s) { unix_socket *peer; unix_state_rlock(s); peer = unix_peer(s); 158 if (peer) sock_hold(peer); 160 unix_state_runlock(s); 161 return peer; } 164 extern __inline__ void unix_release_addr(struct unix_address *addr) { 166 if (atomic_dec_and_test(&addr->refcnt)) kfree(addr); } /* * Check unix socket name: * - should be not zero length. * - if started by not zero, should be NULL terminated (FS object) * - if started by zero, it is abstract name. */ 177 static int unix_mkname(struct sockaddr_un * sunaddr, int len, unsigned *hashp) { 179 if (len <= sizeof(short) || len > sizeof(*sunaddr)) 180 return -EINVAL; 181 if (!sunaddr || sunaddr->sun_family != AF_UNIX) 182 return -EINVAL; 183 if (sunaddr->sun_path[0]) { /* * This may look like an off by one error but it is * a bit more subtle. 108 is the longest valid AF_UNIX * path for a binding. sun_path[108] doesnt as such * exist. However in kernel space we are guaranteed that * it is a valid memory location in our kernel * address buffer. */ 193 if (len > sizeof(*sunaddr)) len = sizeof(*sunaddr); ((char *)sunaddr)[len]=0; len = strlen(sunaddr->sun_path)+1+sizeof(short); 197 return len; } *hashp = unix_hash_fold(csum_partial((char*)sunaddr, len, 0)); 201 return len; } 204 static void __unix_remove_socket(unix_socket *sk) { unix_socket **list = sk->protinfo.af_unix.list; 207 if (list) { 208 if (sk->next) sk->next->prev = sk->prev; 210 if (sk->prev) sk->prev->next = sk->next; 212 if (*list == sk) *list = sk->next; sk->protinfo.af_unix.list = NULL; sk->prev = NULL; sk->next = NULL; __sock_put(sk); } } 221 static void __unix_insert_socket(unix_socket **list, unix_socket *sk) { 223 BUG_TRAP(sk->protinfo.af_unix.list==NULL); sk->protinfo.af_unix.list = list; sk->prev = NULL; sk->next = *list; 228 if (*list) (*list)->prev = sk; *list=sk; sock_hold(sk); } 234 static __inline__ void unix_remove_socket(unix_socket *sk) { write_lock(&unix_table_lock); __unix_remove_socket(sk); 238 write_unlock(&unix_table_lock); } 241 static __inline__ void unix_insert_socket(unix_socket **list, unix_socket *sk) { write_lock(&unix_table_lock); __unix_insert_socket(list, sk); 245 write_unlock(&unix_table_lock); } 248 static unix_socket *__unix_find_socket_byname(struct sockaddr_un *sunname, int len, int type, unsigned hash) { unix_socket *s; 253 for (s=unix_socket_table[hash^type]; s; s=s->next) { if(s->protinfo.af_unix.addr->len==len && 255 memcmp(s->protinfo.af_unix.addr->name, sunname, len) == 0) 256 return s; } 258 return NULL; } static __inline__ unix_socket * 262 unix_find_socket_byname(struct sockaddr_un *sunname, int len, int type, unsigned hash) { unix_socket *s; read_lock(&unix_table_lock); s = __unix_find_socket_byname(sunname, len, type, hash); 269 if (s) sock_hold(s); 271 read_unlock(&unix_table_lock); 272 return s; } 275 static unix_socket *unix_find_socket_byinode(struct inode *i) { unix_socket *s; read_lock(&unix_table_lock); 280 for (s=unix_socket_table[i->i_ino & (UNIX_HASH_SIZE-1)]; s; s=s->next) { struct dentry *dentry = s->protinfo.af_unix.dentry; 284 if(dentry && dentry->d_inode == i) { sock_hold(s); 287 break; } } 290 read_unlock(&unix_table_lock); 291 return s; } 294 static __inline__ int unix_writable(struct sock *sk) { 296 return ((atomic_read(&sk->wmem_alloc)<<2) <= sk->sndbuf); } 299 static void unix_write_space(struct sock *sk) { read_lock(&sk->callback_lock); 302 if (unix_writable(sk)) { 303 if (sk->sleep && waitqueue_active(sk->sleep)) wake_up_interruptible(sk->sleep); sk_wake_async(sk, 2, POLL_OUT); } 307 read_unlock(&sk->callback_lock); } /* When dgram socket disconnects (or changes its peer), we clear its receive * queue of packets arrived from previous peer. First, it allows to do * flow control based only on wmem_alloc; second, sk connected to peer * may receive messages only from that peer. */ 314 static void unix_dgram_disconnected(struct sock *sk, struct sock *other) { 316 if (skb_queue_len(&sk->receive_queue)) { skb_queue_purge(&sk->receive_queue); wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait); /* If one link of bidirectional dgram pipe is disconnected, * we signal error. Messages are lost. Do not make this, * when peer was not connected to us. */ 324 if (!other->dead && unix_peer(other) == sk) { other->err = ECONNRESET; other->error_report(other); } } } 331 static void unix_sock_destructor(struct sock *sk) { skb_queue_purge(&sk->receive_queue); 335 BUG_TRAP(atomic_read(&sk->wmem_alloc) == 0); 336 BUG_TRAP(sk->protinfo.af_unix.list==NULL); 337 BUG_TRAP(sk->socket==NULL); 338 if (sk->dead==0) { printk("Attempt to release alive unix socket: %p\n", sk); 340 return; } 343 if (sk->protinfo.af_unix.addr) unix_release_addr(sk->protinfo.af_unix.addr); atomic_dec(&unix_nr_socks); #ifdef UNIX_REFCNT_DEBUG printk(KERN_DEBUG "UNIX %p is destroyed, %d are still alive.\n", sk, atomic_read(&unix_nr_socks)); #endif 350 MOD_DEC_USE_COUNT; } 353 static int unix_release_sock (unix_socket *sk, int embrion) { struct dentry *dentry; struct vfsmount *mnt; unix_socket *skpair; struct sk_buff *skb; int state; unix_remove_socket(sk); /* Clear state */ unix_state_wlock(sk); sock_orphan(sk); sk->shutdown = SHUTDOWN_MASK; dentry = sk->protinfo.af_unix.dentry; sk->protinfo.af_unix.dentry=NULL; mnt = sk->protinfo.af_unix.mnt; sk->protinfo.af_unix.mnt=NULL; state = sk->state; sk->state = TCP_CLOSE; 373 unix_state_wunlock(sk); wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait); skpair=unix_peer(sk); 379 if (skpair!=NULL) { 380 if (sk->type==SOCK_STREAM) { unix_state_wlock(skpair); skpair->shutdown=SHUTDOWN_MASK; /* No more writes*/ 383 if (!skb_queue_empty(&sk->receive_queue) || embrion) skpair->err = ECONNRESET; 385 unix_state_wunlock(skpair); skpair->state_change(skpair); read_lock(&skpair->callback_lock); sk_wake_async(skpair,1,POLL_HUP); 389 read_unlock(&skpair->callback_lock); } sock_put(skpair); /* It may now die */ unix_peer(sk) = NULL; } /* Try to flush out this socket. Throw out buffers at least */ 397 while((skb=skb_dequeue(&sk->receive_queue))!=NULL) { 399 if (state==TCP_LISTEN) unix_release_sock(skb->sk, 1); /* passed fds are erased in the kfree_skb hook */ kfree_skb(skb); } 405 if (dentry) { dput(dentry); mntput(mnt); } sock_put(sk); /* ---- Socket is dead now and most probably destroyed ---- */ /* * Fixme: BSD difference: In BSD all sockets connected to use get * ECONNRESET and we die on the spot. In Linux we behave * like files and pipes do and wait for the last * dereference. * * Can't we simply set sock->err? * * What the above comment does talk about? --ANK(980817) */ 425 if (atomic_read(&unix_tot_inflight)) unix_gc(); /* Garbage collect fds */ 428 return 0; } 431 static int unix_listen(struct socket *sock, int backlog) { int err; struct sock *sk = sock->sk; err = -EOPNOTSUPP; 437 if (sock->type!=SOCK_STREAM) 438 goto out; /* Only stream sockets accept */ err = -EINVAL; 440 if (!sk->protinfo.af_unix.addr) 441 goto out; /* No listens on an unbound socket */ unix_state_wlock(sk); 443 if (sk->state != TCP_CLOSE && sk->state != TCP_LISTEN) 444 goto out_unlock; 445 if (backlog > sk->max_ack_backlog) wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait); sk->max_ack_backlog=backlog; sk->state=TCP_LISTEN; /* set credentials so connect can copy them */ sk->peercred.pid = current->pid; sk->peercred.uid = current->euid; sk->peercred.gid = current->egid; err = 0; out_unlock: 456 unix_state_wunlock(sk); out: 458 return err; } extern struct proto_ops unix_stream_ops; extern struct proto_ops unix_dgram_ops; 464 static struct sock * unix_create1(struct socket *sock) { struct sock *sk; 468 if (atomic_read(&unix_nr_socks) >= 2*files_stat.max_files) 469 return NULL; 471 MOD_INC_USE_COUNT; sk = sk_alloc(PF_UNIX, GFP_KERNEL, 1); 473 if (!sk) { 474 MOD_DEC_USE_COUNT; 475 return NULL; } atomic_inc(&unix_nr_socks); sock_init_data(sock,sk); sk->write_space = unix_write_space; sk->max_ack_backlog = sysctl_unix_max_dgram_qlen; sk->destruct = unix_sock_destructor; sk->protinfo.af_unix.dentry=NULL; sk->protinfo.af_unix.mnt=NULL; sk->protinfo.af_unix.lock = RW_LOCK_UNLOCKED; atomic_set(&sk->protinfo.af_unix.inflight, 0); init_MUTEX(&sk->protinfo.af_unix.readsem);/* single task reading lock */ init_waitqueue_head(&sk->protinfo.af_unix.peer_wait); sk->protinfo.af_unix.list=NULL; unix_insert_socket(&unix_sockets_unbound, sk); 495 return sk; } 498 static int unix_create(struct socket *sock, int protocol) { 500 if (protocol && protocol != PF_UNIX) 501 return -EPROTONOSUPPORT; sock->state = SS_UNCONNECTED; 505 switch (sock->type) { 506 case SOCK_STREAM: sock->ops = &unix_stream_ops; 508 break; /* * Believe it or not BSD has AF_UNIX, SOCK_RAW though * nothing uses it. */ 513 case SOCK_RAW: sock->type=SOCK_DGRAM; 515 case SOCK_DGRAM: sock->ops = &unix_dgram_ops; 517 break; 518 default: 519 return -ESOCKTNOSUPPORT; } 522 return unix_create1(sock) ? 0 : -ENOMEM; } 525 static int unix_release(struct socket *sock) { unix_socket *sk = sock->sk; 529 if (!sk) 530 return 0; sock->sk = NULL; 534 return unix_release_sock (sk, 0); } 537 static int unix_autobind(struct socket *sock) { struct sock *sk = sock->sk; static u32 ordernum = 1; struct unix_address * addr; int err; down(&sk->protinfo.af_unix.readsem); err = 0; 547 if (sk->protinfo.af_unix.addr) 548 goto out; err = -ENOMEM; addr = kmalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL); 552 if (!addr) 553 goto out; memset(addr, 0, sizeof(*addr) + sizeof(short) + 16); addr->name->sun_family = AF_UNIX; atomic_set(&addr->refcnt, 1); retry: addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short); addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0)); write_lock(&unix_table_lock); ordernum = (ordernum+1)&0xFFFFF; if (__unix_find_socket_byname(addr->name, addr->len, sock->type, 567 addr->hash)) { 568 write_unlock(&unix_table_lock); /* Sanity yield. It is unusual case, but yet... */ 570 if (!(ordernum&0xFF)) { current->policy |= SCHED_YIELD; schedule(); } 574 goto retry; } addr->hash ^= sk->type; __unix_remove_socket(sk); sk->protinfo.af_unix.addr = addr; __unix_insert_socket(&unix_socket_table[addr->hash], sk); 581 write_unlock(&unix_table_lock); err = 0; out: up(&sk->protinfo.af_unix.readsem); 586 return err; } 589 static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len, int type, unsigned hash, int *error) { unix_socket *u; struct nameidata nd; int err = 0; 596 if (sunname->sun_path[0]) { if (path_init(sunname->sun_path, 598 LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd)) err = path_walk(sunname->sun_path, &nd); 600 if (err) 601 goto fail; err = permission(nd.dentry->d_inode,MAY_WRITE); 603 if (err) 604 goto put_fail; err = -ECONNREFUSED; 607 if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) 608 goto put_fail; u=unix_find_socket_byinode(nd.dentry->d_inode); 610 if (!u) 611 goto put_fail; path_release(&nd); err=-EPROTOTYPE; 616 if (u->type != type) { sock_put(u); 618 goto fail; } 620 } else { err = -ECONNREFUSED; u=unix_find_socket_byname(sunname, len, type, hash); 623 if (!u) 624 goto fail; } 626 return u; put_fail: path_release(&nd); fail: *error=err; 632 return NULL; } 636 static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk = sock->sk; struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr; struct dentry * dentry = NULL; struct nameidata nd; int err; unsigned hash; struct unix_address *addr; unix_socket **list; err = -EINVAL; 648 if (sunaddr->sun_family != AF_UNIX) 649 goto out; 651 if (addr_len==sizeof(short)) { err = unix_autobind(sock); 653 goto out; } err = unix_mkname(sunaddr, addr_len, &hash); 657 if (err < 0) 658 goto out; addr_len = err; down(&sk->protinfo.af_unix.readsem); err = -EINVAL; 664 if (sk->protinfo.af_unix.addr) 665 goto out_up; err = -ENOMEM; addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL); 669 if (!addr) 670 goto out_up; memcpy(addr->name, sunaddr, addr_len); addr->len = addr_len; addr->hash = hash^sk->type; atomic_set(&addr->refcnt, 1); 677 if (sunaddr->sun_path[0]) { err = 0; /* * Get the parent directory, calculate the hash for last * component. */ 683 if (path_init(sunaddr->sun_path, LOOKUP_PARENT, &nd)) err = path_walk(sunaddr->sun_path, &nd); 685 if (err) 686 goto out_mknod_parent; /* * Yucky last component or no last component at all? * (foo/., foo/.., /////) */ err = -EEXIST; 692 if (nd.last_type != LAST_NORM) 693 goto out_mknod; /* * Lock the directory. */ down(&nd.dentry->d_inode->i_sem); /* * Do the final lookup. */ dentry = lookup_hash(&nd.last, nd.dentry); err = PTR_ERR(dentry); 703 if (IS_ERR(dentry)) 704 goto out_mknod_unlock; err = -ENOENT; /* * Special case - lookup gave negative, but... we had foo/bar/ * From the vfs_mknod() POV we just have a negative dentry - * all is fine. Let's be bastards - you had / on the end, you've * been asking for (non-existent) directory. -ENOENT for you. */ 712 if (nd.last.name[nd.last.len] && !dentry->d_inode) 713 goto out_mknod_dput; /* * All right, let's create it. */ err = vfs_mknod(nd.dentry->d_inode, dentry, S_IFSOCK|sock->inode->i_mode, 0); 719 if (err) 720 goto out_mknod_dput; up(&nd.dentry->d_inode->i_sem); dput(nd.dentry); nd.dentry = dentry; addr->hash = UNIX_HASH_SIZE; } write_lock(&unix_table_lock); 730 if (!sunaddr->sun_path[0]) { err = -EADDRINUSE; if (__unix_find_socket_byname(sunaddr, addr_len, 733 sk->type, hash)) { unix_release_addr(addr); 735 goto out_unlock; } list = &unix_socket_table[addr->hash]; 739 } else { list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; sk->protinfo.af_unix.dentry = nd.dentry; sk->protinfo.af_unix.mnt = nd.mnt; } err = 0; __unix_remove_socket(sk); sk->protinfo.af_unix.addr = addr; __unix_insert_socket(list, sk); out_unlock: 751 write_unlock(&unix_table_lock); out_up: up(&sk->protinfo.af_unix.readsem); out: 755 return err; out_mknod_dput: dput(dentry); out_mknod_unlock: up(&nd.dentry->d_inode->i_sem); out_mknod: path_release(&nd); out_mknod_parent: 764 if (err==-EEXIST) err=-EADDRINUSE; unix_release_addr(addr); 767 goto out_up; } 770 static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) { struct sock *sk = sock->sk; struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr; struct sock *other; unsigned hash; int err; 779 if (addr->sa_family != AF_UNSPEC) { err = unix_mkname(sunaddr, alen, &hash); 781 if (err < 0) 782 goto out; alen = err; if (sock->passcred && !sk->protinfo.af_unix.addr && 786 (err = unix_autobind(sock)) != 0) 787 goto out; other=unix_find_other(sunaddr, alen, sock->type, hash, &err); 790 if (!other) 791 goto out; unix_state_wlock(sk); err = -EPERM; 796 if (!unix_may_send(sk, other)) 797 goto out_unlock; 798 } else { /* * 1003.1g breaking connected state with AF_UNSPEC */ other = NULL; unix_state_wlock(sk); } /* * If it was connected, reconnect. */ 809 if (unix_peer(sk)) { struct sock *old_peer = unix_peer(sk); unix_peer(sk)=other; 812 unix_state_wunlock(sk); 814 if (other != old_peer) unix_dgram_disconnected(sk, old_peer); sock_put(old_peer); 817 } else { unix_peer(sk)=other; 819 unix_state_wunlock(sk); } 821 return 0; out_unlock: 824 unix_state_wunlock(sk); sock_put(other); out: 827 return err; } 830 static long unix_wait_for_peer(unix_socket *other, long timeo) { int sched; DECLARE_WAITQUEUE(wait, current); 835 __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue_exclusive(&other->protinfo.af_unix.peer_wait, &wait); sched = (!other->dead && !(other->shutdown&RCV_SHUTDOWN) && skb_queue_len(&other->receive_queue) > other->max_ack_backlog); 842 unix_state_runlock(other); 844 if (sched) timeo = schedule_timeout(timeo); 847 __set_current_state(TASK_RUNNING); remove_wait_queue(&other->protinfo.af_unix.peer_wait, &wait); 849 return timeo; } 852 static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr; struct sock *sk = sock->sk; struct sock *newsk = NULL; unix_socket *other = NULL; struct sk_buff *skb = NULL; unsigned hash; int st; int err; long timeo; err = unix_mkname(sunaddr, addr_len, &hash); 866 if (err < 0) 867 goto out; addr_len = err; if (sock->passcred && !sk->protinfo.af_unix.addr && 871 (err = unix_autobind(sock)) != 0) 872 goto out; timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); /* First of all allocate resources. If we will make it after state is locked, we will have to recheck all again in any case. */ err = -ENOMEM; /* create new sock for complete connection */ newsk = unix_create1(NULL); 885 if (newsk == NULL) 886 goto out; /* Allocate skb for sending to listening sock */ skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL); 890 if (skb == NULL) 891 goto out; restart: /* Find listening sock. */ other=unix_find_other(sunaddr, addr_len, sk->type, hash, &err); 896 if (!other) 897 goto out; /* Latch state of peer */ unix_state_rlock(other); /* Apparently VFS overslept socket death. Retry. */ 903 if (other->dead) { 904 unix_state_runlock(other); sock_put(other); 906 goto restart; } err = -ECONNREFUSED; 910 if (other->state != TCP_LISTEN) 911 goto out_unlock; 913 if (skb_queue_len(&other->receive_queue) > other->max_ack_backlog) { err = -EAGAIN; 915 if (!timeo) 916 goto out_unlock; timeo = unix_wait_for_peer(other, timeo); err = sock_intr_errno(timeo); 921 if (signal_pending(current)) 922 goto out; sock_put(other); 924 goto restart; } /* Latch our state. It is tricky place. We need to grab write lock and cannot drop lock on peer. It is dangerous because deadlock is possible. Connect to self case and simultaneous attempt to connect are eliminated by checking socket state. other is TCP_LISTEN, if sk is TCP_LISTEN we check this before attempt to grab lock. Well, and we have to recheck the state after socket locked. */ st = sk->state; 940 switch (st) { 941 case TCP_CLOSE: /* This is ok... continue with connect */ 943 break; 944 case TCP_ESTABLISHED: /* Socket is already connected */ err = -EISCONN; 947 goto out_unlock; 948 default: err = -EINVAL; 950 goto out_unlock; } unix_state_wlock(sk); 955 if (sk->state != st) { 956 unix_state_wunlock(sk); 957 unix_state_runlock(other); sock_put(other); 959 goto restart; } /* The way is open! Fastly set all the necessary fields... */ sock_hold(sk); unix_peer(newsk)=sk; newsk->state=TCP_ESTABLISHED; newsk->type=SOCK_STREAM; newsk->peercred.pid = current->pid; newsk->peercred.uid = current->euid; newsk->peercred.gid = current->egid; newsk->sleep = &newsk->protinfo.af_unix.peer_wait; /* copy address information from listening to new sock*/ 974 if (other->protinfo.af_unix.addr) { atomic_inc(&other->protinfo.af_unix.addr->refcnt); newsk->protinfo.af_unix.addr=other->protinfo.af_unix.addr; } 979 if (other->protinfo.af_unix.dentry) { newsk->protinfo.af_unix.dentry=dget(other->protinfo.af_unix.dentry); newsk->protinfo.af_unix.mnt=mntget(other->protinfo.af_unix.mnt); } /* Set credentials */ sk->peercred = other->peercred; sock_hold(newsk); unix_peer(sk)=newsk; sock->state=SS_CONNECTED; sk->state=TCP_ESTABLISHED; 992 unix_state_wunlock(sk); /* take ten and and send info to listening sock */ skb_queue_tail(&other->receive_queue,skb); 996 unix_state_runlock(other); other->data_ready(other, 0); sock_put(other); 999 return 0; out_unlock: 1002 if (other) 1003 unix_state_runlock(other); out: 1006 if (skb) kfree_skb(skb); 1008 if (newsk) unix_release_sock(newsk, 0); 1010 if (other) sock_put(other); 1012 return err; } 1015 static int unix_socketpair(struct socket *socka, struct socket *sockb) { struct sock *ska=socka->sk, *skb = sockb->sk; /* Join our sockets back to back */ sock_hold(ska); sock_hold(skb); unix_peer(ska)=skb; unix_peer(skb)=ska; ska->peercred.pid = skb->peercred.pid = current->pid; ska->peercred.uid = skb->peercred.uid = current->euid; ska->peercred.gid = skb->peercred.gid = current->egid; 1028 if (ska->type != SOCK_DGRAM) { ska->state=TCP_ESTABLISHED; skb->state=TCP_ESTABLISHED; socka->state=SS_CONNECTED; sockb->state=SS_CONNECTED; } 1035 return 0; } 1038 static int unix_accept(struct socket *sock, struct socket *newsock, int flags) { unix_socket *sk = sock->sk; unix_socket *tsk; struct sk_buff *skb; int err; err = -EOPNOTSUPP; 1046 if (sock->type!=SOCK_STREAM) 1047 goto out; err = -EINVAL; 1050 if (sk->state!=TCP_LISTEN) 1051 goto out; /* If socket state is TCP_LISTEN it cannot change (for now...), * so that no locks are necessary. */ skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err); 1058 if (!skb) 1059 goto out; tsk = skb->sk; skb_free_datagram(sk, skb); wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); /* attach accepted sock to socket */ unix_state_wlock(tsk); newsock->state = SS_CONNECTED; sock_graft(tsk, newsock); 1069 unix_state_wunlock(tsk); 1070 return 0; out: 1073 return err; } 1077 static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { struct sock *sk = sock->sk; struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr; int err = 0; 1083 if (peer) { sk = unix_peer_get(sk); err = -ENOTCONN; 1087 if (!sk) 1088 goto out; err = 0; 1090 } else { sock_hold(sk); } unix_state_rlock(sk); 1095 if (!sk->protinfo.af_unix.addr) { sunaddr->sun_family = AF_UNIX; sunaddr->sun_path[0] = 0; *uaddr_len = sizeof(short); 1099 } else { struct unix_address *addr = sk->protinfo.af_unix.addr; *uaddr_len = addr->len; memcpy(sunaddr, addr->name, *uaddr_len); } 1105 unix_state_runlock(sk); sock_put(sk); out: 1108 return err; } 1111 static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) { int i; scm->fp = UNIXCB(skb).fp; skb->destructor = sock_wfree; UNIXCB(skb).fp = NULL; 1119 for (i=scm->fp->count-1; i>=0; i--) unix_notinflight(scm->fp->fp[i]); } 1123 static void unix_destruct_fds(struct sk_buff *skb) { struct scm_cookie scm; memset(&scm, 0, sizeof(scm)); unix_detach_fds(&scm, skb); /* Alas, it calls VFS */ /* So fscking what? fput() had been SMP-safe since the last Summer */ scm_destroy(&scm); sock_wfree(skb); } 1135 static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) { int i; 1138 for (i=scm->fp->count-1; i>=0; i--) unix_inflight(scm->fp->fp[i]); UNIXCB(skb).fp = scm->fp; skb->destructor = unix_destruct_fds; scm->fp = NULL; } /* * Send AF_UNIX data. */ 1149 static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) { struct sock *sk = sock->sk; struct sockaddr_un *sunaddr=msg->msg_name; unix_socket *other = NULL; int namelen = 0; /* fake GCC */ int err; unsigned hash; struct sk_buff *skb; long timeo; err = -EOPNOTSUPP; 1162 if (msg->msg_flags&MSG_OOB) 1163 goto out; 1165 if (msg->msg_namelen) { err = unix_mkname(sunaddr, msg->msg_namelen, &hash); 1167 if (err < 0) 1168 goto out; namelen = err; 1170 } else { sunaddr = NULL; err = -ENOTCONN; other = unix_peer_get(sk); 1174 if (!other) 1175 goto out; } if (sock->passcred && !sk->protinfo.af_unix.addr && 1179 (err = unix_autobind(sock)) != 0) 1180 goto out; err = -EMSGSIZE; 1183 if ((unsigned)len > sk->sndbuf - 32) 1184 goto out; skb = sock_alloc_send_skb(sk, len, 0, msg->msg_flags&MSG_DONTWAIT, &err); 1187 if (skb==NULL) 1188 goto out; memcpy(UNIXCREDS(skb), &scm->creds, sizeof(struct ucred)); 1191 if (scm->fp) unix_attach_fds(scm, skb); skb->h.raw = skb->data; err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); 1196 if (err) 1197 goto out_free; timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); restart: 1202 if (!other) { err = -ECONNRESET; 1204 if (sunaddr == NULL) 1205 goto out_free; other = unix_find_other(sunaddr, namelen, sk->type, hash, &err); 1208 if (other==NULL) 1209 goto out_free; } unix_state_rlock(other); err = -EPERM; 1214 if (!unix_may_send(sk, other)) 1215 goto out_unlock; 1217 if (other->dead) { /* * Check with 1003.1g - what should * datagram error */ 1222 unix_state_runlock(other); sock_put(other); err = 0; unix_state_wlock(sk); 1227 if (unix_peer(sk) == other) { unix_peer(sk)=NULL; 1229 unix_state_wunlock(sk); unix_dgram_disconnected(sk, other); sock_put(other); err = -ECONNREFUSED; 1234 } else { 1235 unix_state_wunlock(sk); } other = NULL; 1239 if (err) 1240 goto out_free; 1241 goto restart; } err = -EPIPE; 1245 if (other->shutdown&RCV_SHUTDOWN) 1246 goto out_unlock; if (unix_peer(other) != sk && 1249 skb_queue_len(&other->receive_queue) > other->max_ack_backlog) { 1250 if (!timeo) { err = -EAGAIN; 1252 goto out_unlock; } timeo = unix_wait_for_peer(other, timeo); err = sock_intr_errno(timeo); 1258 if (signal_pending(current)) 1259 goto out_free; 1261 goto restart; } skb_queue_tail(&other->receive_queue, skb); 1265 unix_state_runlock(other); other->data_ready(other, len); sock_put(other); 1268 return len; out_unlock: 1271 unix_state_runlock(other); out_free: kfree_skb(skb); out: 1275 if (other) sock_put(other); 1277 return err; } 1281 static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) { struct sock *sk = sock->sk; unix_socket *other = NULL; struct sockaddr_un *sunaddr=msg->msg_name; int err,size; struct sk_buff *skb; int limit=0; int sent=0; err = -EOPNOTSUPP; 1293 if (msg->msg_flags&MSG_OOB) 1294 goto out_err; 1296 if (msg->msg_namelen) { err = (sk->state==TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP); 1298 goto out_err; 1299 } else { sunaddr = NULL; err = -ENOTCONN; other = unix_peer_get(sk); 1303 if (!other) 1304 goto out_err; } 1307 if (sk->shutdown&SEND_SHUTDOWN) 1308 goto pipe_err; 1310 while(sent < len) { /* * Optimisation for the fact that under 0.01% of X messages typically * need breaking up. */ size=len-sent; /* Keep two messages in the pipe so it schedules better */ 1320 if (size > sk->sndbuf/2 - 16) size = sk->sndbuf/2 - 16; /* * Keep to page sized kmalloc()'s as various people * have suggested. Big mallocs stress the vm too * much. */ 1329 if (size > PAGE_SIZE-16) limit = PAGE_SIZE-16; /* Fall back to a page if we can't grab a big buffer this instant */ 1331 else limit = 0; /* Otherwise just grab and wait */ /* * Grab a buffer */ skb=sock_alloc_send_skb(sk,size,limit,msg->msg_flags&MSG_DONTWAIT, &err); 1340 if (skb==NULL) 1341 goto out_err; /* * If you pass two values to the sock_alloc_send_skb * it tries to grab the large buffer with GFP_BUFFER * (which can fail easily), and if it fails grab the * fallback size buffer which is under a page and will * succeed. [Alan] */ size = min(size, skb_tailroom(skb)); memcpy(UNIXCREDS(skb), &scm->creds, sizeof(struct ucred)); 1353 if (scm->fp) unix_attach_fds(scm, skb); 1356 if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) { kfree_skb(skb); 1358 goto out_err; } unix_state_rlock(other); 1363 if (other->dead || (other->shutdown & RCV_SHUTDOWN)) 1364 goto pipe_err_free; skb_queue_tail(&other->receive_queue, skb); 1367 unix_state_runlock(other); other->data_ready(other, size); sent+=size; } sock_put(other); 1372 return sent; pipe_err_free: 1375 unix_state_runlock(other); kfree_skb(skb); pipe_err: 1378 if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL)) send_sig(SIGPIPE,current,0); err = -EPIPE; out_err: 1382 if (other) sock_put(other); 1384 return sent ? : err; } 1387 static void unix_copy_addr(struct msghdr *msg, struct sock *sk) { msg->msg_namelen = sizeof(short); 1390 if (sk->protinfo.af_unix.addr) { msg->msg_namelen=sk->protinfo.af_unix.addr->len; memcpy(msg->msg_name, sk->protinfo.af_unix.addr->name, sk->protinfo.af_unix.addr->len); } } 1398 static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) { struct sock *sk = sock->sk; int noblock = flags & MSG_DONTWAIT; struct sk_buff *skb; int err; err = -EOPNOTSUPP; 1407 if (flags&MSG_OOB) 1408 goto out; msg->msg_namelen = 0; skb = skb_recv_datagram(sk, flags, noblock, &err); 1413 if (!skb) 1414 goto out; wake_up_interruptible(&sk->protinfo.af_unix.peer_wait); 1418 if (msg->msg_name) unix_copy_addr(msg, skb->sk); 1421 if (size > skb->len) size = skb->len; 1423 else if (size < skb->len) msg->msg_flags |= MSG_TRUNC; err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); 1427 if (err) 1428 goto out_free; scm->creds = *UNIXCREDS(skb); 1432 if (!(flags & MSG_PEEK)) { 1434 if (UNIXCB(skb).fp) unix_detach_fds(scm, skb); } 1437 else { /* It is questionable: on PEEK we could: - do not return fds - good, but too simple 8) - return fds, and do not return them on read (old strategy, apparently wrong) - clone fds (I choosed it for now, it is the most universal solution) POSIX 1003.1g does not actually define this clearly at all. POSIX 1003.1g doesn't define a lot of things clearly however! */ 1451 if (UNIXCB(skb).fp) scm->fp = scm_fp_dup(UNIXCB(skb).fp); } err = size; out_free: skb_free_datagram(sk,skb); out: 1459 return err; } /* * Sleep until data has arrive. But check for races.. */ 1466 static long unix_stream_data_wait(unix_socket * sk, long timeo) { DECLARE_WAITQUEUE(wait, current); unix_state_rlock(sk); add_wait_queue(sk->sleep, &wait); 1474 for (;;) { 1475 set_current_state(TASK_INTERRUPTIBLE); if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) || signal_pending(current) || 1481 !timeo) 1482 break; set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags); 1485 unix_state_runlock(sk); timeo = schedule_timeout(timeo); unix_state_rlock(sk); clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags); } 1491 __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); 1493 unix_state_runlock(sk); 1494 return timeo; } 1499 static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) { struct sock *sk = sock->sk; struct sockaddr_un *sunaddr=msg->msg_name; int copied = 0; int check_creds = 0; int target; int err = 0; long timeo; err = -EINVAL; 1511 if (sk->state != TCP_ESTABLISHED) 1512 goto out; err = -EOPNOTSUPP; 1515 if (flags&MSG_OOB) 1516 goto out; target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); msg->msg_namelen = 0; /* Lock the socket to prevent queue disordering * while sleeps in memcpy_tomsg */ down(&sk->protinfo.af_unix.readsem); 1529 do { int chunk; struct sk_buff *skb; skb=skb_dequeue(&sk->receive_queue); 1535 if (skb==NULL) { 1537 if (copied >= target) 1538 break; /* * POSIX 1003.1g mandates this order. */ 1544 if ((err = sock_error(sk)) != 0) 1545 break; 1546 if (sk->shutdown & RCV_SHUTDOWN) 1547 break; err = -EAGAIN; 1549 if (!timeo) 1550 break; up(&sk->protinfo.af_unix.readsem); timeo = unix_stream_data_wait(sk, timeo); 1555 if (signal_pending(current)) { err = sock_intr_errno(timeo); 1557 goto out; } down(&sk->protinfo.af_unix.readsem); 1560 continue; } 1563 if (check_creds) { /* Never glue messages from different writers */ 1565 if (memcmp(UNIXCREDS(skb), &scm->creds, sizeof(scm->creds)) != 0) { skb_queue_head(&sk->receive_queue, skb); 1567 break; } 1569 } else { /* Copy credentials */ scm->creds = *UNIXCREDS(skb); check_creds = 1; } /* Copy address just once */ 1576 if (sunaddr) { unix_copy_addr(msg, skb->sk); sunaddr = NULL; } chunk = min(skb->len, size); 1583 if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { skb_queue_head(&sk->receive_queue, skb); 1585 if (copied == 0) copied = -EFAULT; 1587 break; } copied += chunk; size -= chunk; /* Mark read part of skb as used */ 1593 if (!(flags & MSG_PEEK)) { skb_pull(skb, chunk); 1597 if (UNIXCB(skb).fp) unix_detach_fds(scm, skb); /* put the skb back if we didn't use it up.. */ 1601 if (skb->len) { skb_queue_head(&sk->receive_queue, skb); 1604 break; } kfree_skb(skb); 1609 if (scm->fp) 1610 break; } 1612 else { /* It is questionable, see note in unix_dgram_recvmsg. */ 1616 if (UNIXCB(skb).fp) scm->fp = scm_fp_dup(UNIXCB(skb).fp); /* put message back and return */ skb_queue_head(&sk->receive_queue, skb); 1621 break; } 1623 } while (size); up(&sk->protinfo.af_unix.readsem); out: 1627 return copied ? : err; } 1630 static int unix_shutdown(struct socket *sock, int mode) { struct sock *sk = sock->sk; unix_socket *other; mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); 1637 if (mode) { unix_state_wlock(sk); sk->shutdown |= mode; other=unix_peer(sk); 1641 if (other) sock_hold(other); 1643 unix_state_wunlock(sk); sk->state_change(sk); 1646 if (other && sk->type == SOCK_STREAM) { int peer_mode = 0; 1649 if (mode&RCV_SHUTDOWN) peer_mode |= SEND_SHUTDOWN; 1651 if (mode&SEND_SHUTDOWN) peer_mode |= RCV_SHUTDOWN; unix_state_wlock(other); other->shutdown |= peer_mode; 1655 unix_state_wunlock(other); other->state_change(other); read_lock(&other->callback_lock); 1658 if (peer_mode == SHUTDOWN_MASK) sk_wake_async(other,1,POLL_HUP); 1660 else if (peer_mode & RCV_SHUTDOWN) sk_wake_async(other,1,POLL_IN); 1662 read_unlock(&other->callback_lock); } 1664 if (other) sock_put(other); } 1667 return 0; } 1670 static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; long amount=0; int err; 1676 switch(cmd) { 1678 case SIOCOUTQ: amount = atomic_read(&sk->wmem_alloc); err = put_user(amount, (int *)arg); 1681 break; 1682 case SIOCINQ: { struct sk_buff *skb; 1685 if (sk->state==TCP_LISTEN) { err = -EINVAL; 1687 break; } spin_lock(&sk->receive_queue.lock); 1691 if((skb=skb_peek(&sk->receive_queue))!=NULL) amount=skb->len; 1693 spin_unlock(&sk->receive_queue.lock); err = put_user(amount, (int *)arg); 1695 break; } 1698 default: err = dev_ioctl(cmd, (void *)arg); 1700 break; } 1702 return err; } 1705 static unsigned int unix_poll(struct file * file, struct socket *sock, poll_table *wait) { struct sock *sk = sock->sk; unsigned int mask; poll_wait(file, sk->sleep, wait); mask = 0; /* exceptional events? */ 1714 if (sk->err) mask |= POLLERR; 1716 if (sk->shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* readable? */ 1720 if (!skb_queue_empty(&sk->receive_queue) || (sk->shutdown&RCV_SHUTDOWN)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ 1724 if (sk->type == SOCK_STREAM && sk->state==TCP_CLOSE) mask |= POLLHUP; /* * we set writable also when the other side has shut down the * connection. This prevents stuck sockets. */ 1731 if (unix_writable(sk)) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; 1734 return mask; } #ifdef CONFIG_PROC_FS 1739 static int unix_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data) { off_t pos=0; off_t begin=0; int len=0; int i; unix_socket *s; len+= sprintf(buffer,"Num RefCount Protocol Flags Type St " "Inode Path\n"); read_lock(&unix_table_lock); 1752 forall_unix_sockets (i,s) { unix_state_rlock(s); len+=sprintf(buffer+len,"%p: %08X %08X %08X %04X %02X %5ld", s, atomic_read(&s->refcnt), 0, s->state == TCP_LISTEN ? __SO_ACCEPTCON : 0, s->type, s->socket ? (s->state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) : (s->state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING), sock_i_ino(s)); 1767 if (s->protinfo.af_unix.addr) { buffer[len++] = ' '; memcpy(buffer+len, s->protinfo.af_unix.addr->name->sun_path, s->protinfo.af_unix.addr->len-sizeof(short)); 1772 if (!UNIX_ABSTRACT(s)) len--; 1774 else buffer[len] = '@'; len += s->protinfo.af_unix.addr->len - sizeof(short); } 1778 unix_state_runlock(s); buffer[len++]='\n'; pos = begin + len; 1783 if(pos<offset) { len=0; begin=pos; } 1788 if(pos>offset+length) 1789 goto done; } *eof = 1; done: 1793 read_unlock(&unix_table_lock); *start=buffer+(offset-begin); len-=(offset-begin); 1796 if(len>length) len=length; 1798 if (len < 0) len = 0; 1800 return len; } #endif struct proto_ops unix_stream_ops = { family: PF_UNIX, release: unix_release, bind: unix_bind, connect: unix_stream_connect, socketpair: unix_socketpair, accept: unix_accept, getname: unix_getname, poll: unix_poll, ioctl: unix_ioctl, listen: unix_listen, shutdown: unix_shutdown, setsockopt: sock_no_setsockopt, getsockopt: sock_no_getsockopt, sendmsg: unix_stream_sendmsg, recvmsg: unix_stream_recvmsg, mmap: sock_no_mmap, }; struct proto_ops unix_dgram_ops = { family: PF_UNIX, release: unix_release, bind: unix_bind, connect: unix_dgram_connect, socketpair: unix_socketpair, accept: sock_no_accept, getname: unix_getname, poll: datagram_poll, ioctl: unix_ioctl, listen: sock_no_listen, shutdown: unix_shutdown, setsockopt: sock_no_setsockopt, getsockopt: sock_no_getsockopt, sendmsg: unix_dgram_sendmsg, recvmsg: unix_dgram_recvmsg, mmap: sock_no_mmap, }; struct net_proto_family unix_family_ops = { PF_UNIX, unix_create }; #ifdef CONFIG_SYSCTL extern void unix_sysctl_register(void); extern void unix_sysctl_unregister(void); #endif 1854 static int __init af_unix_init(void) { struct sk_buff *dummy_skb; printk(KERN_INFO "NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.\n"); 1859 if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) { printk(KERN_CRIT "unix_proto_init: panic\n"); 1862 return -1; } sock_register(&unix_family_ops); #ifdef CONFIG_PROC_FS create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL); #endif #ifdef CONFIG_SYSCTL unix_sysctl_register(); #endif 1873 return 0; } 1876 static void __exit af_unix_exit(void) { sock_unregister(PF_UNIX); #ifdef CONFIG_SYSCTL unix_sysctl_unregister(); #endif #ifdef CONFIG_PROC_FS remove_proc_entry("net/unix", 0); #endif } module_init(af_unix_init); module_exit(af_unix_exit); /* * Local variables: * compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c" * End: */