root/net/unix/af_unix.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. unix_mkname
  2. unix_remove_socket
  3. unix_insert_socket
  4. unix_find_socket
  5. unix_destroy_timer
  6. unix_delayed_delete
  7. unix_destroy_socket
  8. unix_fcntl
  9. unix_setsockopt
  10. unix_getsockopt
  11. unix_listen
  12. def_callback1
  13. def_callback2
  14. def_callback3
  15. unix_create
  16. unix_dup
  17. unix_release
  18. unix_find_other
  19. unix_bind
  20. unix_connect
  21. unix_socketpair
  22. unix_accept
  23. unix_getname
  24. unix_copyrights
  25. unix_returnrights
  26. unix_fd_copy
  27. unix_fd_free
  28. unix_files_free
  29. unix_detach_fds
  30. unix_destruct_fds
  31. unix_attach_fds
  32. unix_sendmsg
  33. unix_data_wait
  34. unix_recvmsg
  35. unix_shutdown
  36. unix_select
  37. unix_ioctl
  38. unix_get_info
  39. unix_proto_init

   1 /*
   2  * NET3:        Implementation of BSD Unix domain sockets.
   3  *
   4  * Authors:     Alan Cox, <alan@cymru.net>
   5  *
   6  *              Currently this contains all but the file descriptor passing code.
   7  *              Before that goes in the odd bugs in the iovec handlers need 
   8  *              fixing, and this bit testing. BSD fd passing is not a trivial part
   9  *              of the exercise it turns out. Anyone like writing garbage collectors.
  10  *
  11  *              This program is free software; you can redistribute it and/or
  12  *              modify it under the terms of the GNU General Public License
  13  *              as published by the Free Software Foundation; either version
  14  *              2 of the License, or (at your option) any later version.
  15  *
  16  * Fixes:
  17  *              Linus Torvalds  :       Assorted bug cures.
  18  *              Niibe Yutaka    :       async I/O support.
  19  *              Carsten Paeth   :       PF_UNIX check, address fixes.
  20  *              Alan Cox        :       Limit size of allocated blocks.
  21  *              Alan Cox        :       Fixed the stupid socketpair bug.
  22  *              Alan Cox        :       BSD compatibility fine tuning.
  23  *              Alan Cox        :       Fixed a bug in connect when interrupted.
  24  *              Alan Cox        :       Sorted out a proper draft version of
  25  *                                      file descriptor passing hacked up from
  26  *                                      Mike Shaver's work.
  27  *
  28  *
  29  * Known differences from reference BSD that was tested:
  30  *
  31  *      [TO FIX]
  32  *      No fd passing yet.
  33  *      ECONNREFUSED is not returned from one end of a connected() socket to the
  34  *              other the moment one end closes.
  35  *      fstat() doesn't return st_dev=NODEV, and give the blksize as high water mark
  36  *              and a fake inode identifier (nor the BSD first socket fstat twice bug).
  37  *      [NOT TO FIX]
  38  *      accept() returns a path name even if the connecting socket has closed
  39  *              in the meantime (BSD loses the path and gives up).
  40  *      accept() returns 0 length path for an unbound connector. BSD returns 16
  41  *              and a null first byte in the path (but not for gethost/peername - BSD bug ??)
  42  *      socketpair(...SOCK_RAW..) doesnt panic the kernel.
  43  */
  44 
  45 #include <linux/config.h>
  46 #include <linux/kernel.h>
  47 #include <linux/major.h>
  48 #include <linux/signal.h>
  49 #include <linux/sched.h>
  50 #include <linux/errno.h>
  51 #include <linux/string.h>
  52 #include <linux/stat.h>
  53 #include <linux/socket.h>
  54 #include <linux/un.h>
  55 #include <linux/fcntl.h>
  56 #include <linux/termios.h>
  57 #include <linux/socket.h>
  58 #include <linux/sockios.h>
  59 #include <linux/net.h>
  60 #include <linux/in.h>
  61 #include <linux/fs.h>
  62 #include <linux/malloc.h>
  63 #include <asm/segment.h>
  64 #include <linux/skbuff.h>
  65 #include <linux/netdevice.h>
  66 #include <net/sock.h>
  67 #include <net/tcp.h>
  68 #include <net/af_unix.h>
  69 #include <linux/proc_fs.h>
  70 
  71 static unix_socket *unix_socket_list=NULL;
  72 
  73 #define min(a,b)        (((a)<(b))?(a):(b))
  74 
  75 /*
  76  *      Make sure the unix name is null-terminated.
  77  */
  78  
  79 static inline void unix_mkname(struct sockaddr_un * sunaddr, unsigned long len)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81         if (len >= sizeof(*sunaddr))
  82                 len = sizeof(*sunaddr)-1;
  83         ((char *)sunaddr)[len]=0;
  84 }
  85 
  86 /*
  87  *      Note: Sockets may not be removed _during_ an interrupt or net_bh
  88  *      handler using this technique. They can be added although we do not
  89  *      use this facility.
  90  */
  91  
  92 static void unix_remove_socket(unix_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         unix_socket **s;
  95         
  96         cli();
  97         s=&unix_socket_list;
  98 
  99         while(*s!=NULL)
 100         {
 101                 if(*s==sk)
 102                 {
 103                         *s=sk->next;
 104                         sti();
 105                         return;
 106                 }
 107                 s=&((*s)->next);
 108         }
 109         sti();
 110 }
 111 
 112 static void unix_insert_socket(unix_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 113 {
 114         cli();
 115         sk->next=unix_socket_list;
 116         unix_socket_list=sk;
 117         sti();
 118 }
 119 
 120 static unix_socket *unix_find_socket(struct inode *i)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122         unix_socket *s;
 123         cli();
 124         s=unix_socket_list;
 125         while(s)
 126         {
 127                 if(s->protinfo.af_unix.inode==i)
 128                 {
 129                         sti();
 130                         return(s);
 131                 }
 132                 s=s->next;
 133         }
 134         sti();
 135         return(NULL);
 136 }
 137 
 138 /*
 139  *      Delete a unix socket. We have to allow for deferring this on a timer.
 140  */
 141 
 142 static void unix_destroy_timer(unsigned long data)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144         unix_socket *sk=(unix_socket *)data;
 145         if(sk->protinfo.af_unix.locks==0 && sk->wmem_alloc==0)
 146         {
 147                 if(sk->protinfo.af_unix.name)
 148                         kfree(sk->protinfo.af_unix.name);
 149                 kfree_s(sk,sizeof(*sk));
 150                 return;
 151         }
 152         
 153         /*
 154          *      Retry;
 155          */
 156          
 157         sk->timer.expires=jiffies+10*HZ;        /* No real hurry try it every 10 seconds or so */
 158         add_timer(&sk->timer);
 159 }
 160          
 161          
 162 static void unix_delayed_delete(unix_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164         sk->timer.data=(unsigned long)sk;
 165         sk->timer.expires=jiffies+HZ;           /* Normally 1 second after will clean up. After that we try every 10 */
 166         sk->timer.function=unix_destroy_timer;
 167         add_timer(&sk->timer);
 168 }
 169         
 170 static void unix_destroy_socket(unix_socket *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172         struct sk_buff *skb;
 173 
 174         unix_remove_socket(sk);
 175         
 176         while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
 177         {
 178                 if(sk->state==TCP_LISTEN)
 179                 {
 180                         unix_socket *osk=skb->sk;
 181                         osk->state=TCP_CLOSE;
 182                         kfree_skb(skb, FREE_WRITE);     /* Now surplus - free the skb first before the socket */
 183                         osk->state_change(osk);         /* So the connect wakes and cleans up (if any) */
 184                         /* osk will be destroyed when it gets to close or the timer fires */                    
 185                 }
 186                 else
 187                 {
 188                         /* passed fds are erased where?? */
 189                         kfree_skb(skb,FREE_WRITE);
 190                 }
 191         }
 192         
 193         if(sk->protinfo.af_unix.inode!=NULL)
 194         {
 195                 iput(sk->protinfo.af_unix.inode);
 196                 sk->protinfo.af_unix.inode=NULL;
 197         }
 198         
 199         if(--sk->protinfo.af_unix.locks==0 && sk->wmem_alloc==0)
 200         {
 201                 if(sk->protinfo.af_unix.name)
 202                         kfree(sk->protinfo.af_unix.name);
 203                 kfree_s(sk,sizeof(*sk));
 204         }
 205         else
 206         {
 207                 sk->dead=1;
 208                 unix_delayed_delete(sk);        /* Try every so often until buffers are all freed */
 209         }
 210 }
 211 
 212 /*
 213  *      Fixme: We need async I/O on AF_UNIX doing next.
 214  */
 215  
 216 static int unix_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218         return -EINVAL;
 219 }
 220 
 221 /*
 222  *      Yes socket options work with the new unix domain socketry!!!!!!!
 223  */
 224  
 225 static int unix_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227         unix_socket *sk=sock->data;
 228         if(level!=SOL_SOCKET)
 229                 return -EOPNOTSUPP;
 230         return sock_setsockopt(sk,level,optname,optval,optlen); 
 231 }
 232 
 233 static int unix_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 234 {
 235         unix_socket *sk=sock->data;
 236         if(level!=SOL_SOCKET)
 237                 return -EOPNOTSUPP;
 238         return sock_getsockopt(sk,level,optname,optval,optlen);
 239 }
 240 
 241 static int unix_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 242 {
 243         unix_socket *sk=sock->data;
 244         if(sk->type!=SOCK_STREAM)
 245                 return -EOPNOTSUPP;             /* Only stream sockets accept */
 246         if(sk->protinfo.af_unix.name==NULL)
 247                 return -EINVAL;                 /* No listens on an unbound socket */
 248         sk->max_ack_backlog=backlog;
 249         sk->state=TCP_LISTEN;
 250         return 0;
 251 }
 252 
 253 static void def_callback1(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 254 {
 255         if(!sk->dead)
 256                 wake_up_interruptible(sk->sleep);
 257 }
 258 
 259 static void def_callback2(struct sock *sk, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 260 {
 261         if(!sk->dead)
 262         {
 263                 wake_up_interruptible(sk->sleep);
 264                 sock_wake_async(sk->socket, 1);
 265         }
 266 }
 267 
 268 static void def_callback3(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 269 {
 270         if(!sk->dead)
 271         {
 272                 wake_up_interruptible(sk->sleep);
 273                 sock_wake_async(sk->socket, 2);
 274         }
 275 }
 276 
 277 static int unix_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 278 {
 279         unix_socket *sk;
 280         if(protocol && protocol != PF_UNIX)
 281                 return -EPROTONOSUPPORT;
 282         sk=(unix_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
 283         if(sk==NULL)
 284                 return -ENOMEM;
 285         switch(sock->type)
 286         {
 287                 case SOCK_STREAM:
 288                         break;
 289                 /*
 290                  *      Believe it or not BSD has AF_UNIX, SOCK_RAW though
 291                  *      nothing uses it.
 292                  */
 293                 case SOCK_RAW:
 294                         sock->type=SOCK_DGRAM;
 295                 case SOCK_DGRAM:
 296                         break;
 297                 default:
 298                         kfree_s(sk,sizeof(*sk));
 299                         return -ESOCKTNOSUPPORT;
 300         }
 301         sk->type=sock->type;
 302         init_timer(&sk->timer);
 303         skb_queue_head_init(&sk->write_queue);
 304         skb_queue_head_init(&sk->receive_queue);
 305         skb_queue_head_init(&sk->back_log);
 306         sk->protinfo.af_unix.family=AF_UNIX;
 307         sk->protinfo.af_unix.inode=NULL;
 308         sk->protinfo.af_unix.locks=1;           /* Us */
 309         sk->protinfo.af_unix.readsem=MUTEX;     /* single task reading lock */
 310         sk->protinfo.af_unix.name=NULL;
 311         sk->protinfo.af_unix.other=NULL;
 312         sk->protocol=0;
 313         sk->rmem_alloc=0;
 314         sk->wmem_alloc=0;
 315         sk->dead=0;
 316         sk->next=NULL;
 317         sk->broadcast=0;
 318         sk->rcvbuf=SK_RMEM_MAX;
 319         sk->sndbuf=SK_WMEM_MAX;
 320         sk->allocation=GFP_KERNEL;
 321         sk->users=0;
 322         sk->bsdism=0;
 323         sk->debug=0;
 324         sk->prot=NULL;
 325         sk->err=0;
 326         sk->localroute=0;
 327         sk->send_head=NULL;
 328         sk->state=TCP_CLOSE;
 329         sk->priority=SOPRI_NORMAL;
 330         sk->ack_backlog=0;
 331         sk->shutdown=0;
 332         sk->state_change=def_callback1;
 333         sk->data_ready=def_callback2;
 334         sk->write_space=def_callback3;
 335         sk->error_report=def_callback1;
 336         sk->mtu=4096;
 337         sk->socket=sock;
 338         sock->data=(void *)sk;
 339         sk->sleep=sock->wait;
 340         sk->zapped=0;
 341         unix_insert_socket(sk);
 342         return 0;
 343 }
 344 
 345 static int unix_dup(struct socket *newsock, struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347         return unix_create(newsock,0);
 348 }
 349 
 350 static int unix_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 351 {
 352         unix_socket *sk=sock->data;
 353         unix_socket *skpair;
 354         
 355         /* May not have data attached */
 356         
 357         if(sk==NULL)
 358                 return 0;
 359                 
 360         sk->state_change(sk);
 361         sk->dead=1;
 362         skpair=(unix_socket *)sk->protinfo.af_unix.other;       /* Person we send to (default) */
 363         if(sk->type==SOCK_STREAM && skpair!=NULL && skpair->state!=TCP_LISTEN)
 364         {
 365                 skpair->shutdown=SHUTDOWN_MASK;         /* No more writes */
 366                 skpair->state_change(skpair);           /* Wake any blocked writes */
 367         }
 368         if(skpair!=NULL)
 369                 skpair->protinfo.af_unix.locks--;       /* It may now die */
 370         sk->protinfo.af_unix.other=NULL;                /* No pair */
 371         unix_destroy_socket(sk);                        /* Try and flush out this socket. Throw our buffers at least */
 372         
 373         /*
 374          *      FIXME: BSD difference: In BSD all sockets connected to use get ECONNRESET and we die on the spot. In
 375          *      Linux we behave like files and pipes do and wait for the last dereference.
 376          */
 377          
 378         return 0;
 379 }
 380 
 381 
 382 static unix_socket *unix_find_other(char *path, int *error)
     /* [previous][next][first][last][top][bottom][index][help] */
 383 {
 384         int old_fs;
 385         int err;
 386         struct inode *inode;
 387         unix_socket *u;
 388         
 389         old_fs=get_fs();
 390         set_fs(get_ds());
 391         err = open_namei(path, 2, S_IFSOCK, &inode, NULL);
 392         set_fs(old_fs);
 393         if(err<0)
 394         {
 395                 *error=err;
 396                 return NULL;
 397         }
 398         u=unix_find_socket(inode);
 399         iput(inode);
 400         if(u==NULL)
 401         {
 402                 *error=-ECONNREFUSED;
 403                 return NULL;
 404         }
 405         return u;
 406 }
 407 
 408 
 409 static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 410 {
 411         struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
 412         unix_socket *sk=sock->data;
 413         int old_fs;
 414         int err;
 415         
 416         if(sk->protinfo.af_unix.name)
 417                 return -EINVAL;         /* Already bound */
 418         
 419         if(addr_len>sizeof(struct sockaddr_un) || addr_len<3 || sunaddr->sun_family!=AF_UNIX)
 420                 return -EINVAL;
 421         unix_mkname(sunaddr, addr_len);
 422         /*
 423          *      Put ourselves in the filesystem
 424          */
 425         if(sk->protinfo.af_unix.inode!=NULL)
 426                 return -EINVAL;
 427         
 428         sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
 429         if(sk->protinfo.af_unix.name==NULL)
 430                 return -ENOMEM;
 431         memcpy(sk->protinfo.af_unix.name, sunaddr->sun_path, addr_len+1);
 432         
 433         old_fs=get_fs();
 434         set_fs(get_ds());
 435         
 436         err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
 437         if(err==0)
 438                 err=open_namei(sk->protinfo.af_unix.name, 2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
 439         
 440         set_fs(old_fs);
 441         
 442         if(err<0)
 443         {
 444                 kfree_s(sk->protinfo.af_unix.name,addr_len+1);
 445                 sk->protinfo.af_unix.name=NULL;
 446                 if(err==-EEXIST)
 447                         return -EADDRINUSE;
 448                 else
 449                         return err;
 450         }
 451         
 452         return 0;
 453         
 454 }
 455 
 456 static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 457 {
 458         unix_socket *sk=sock->data;
 459         struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
 460         unix_socket *other;
 461         struct sk_buff *skb;
 462         int err;
 463 
 464         if(sk->type==SOCK_STREAM && sk->protinfo.af_unix.other)
 465         {
 466                 if(sock->state==SS_CONNECTING && sk->state==TCP_ESTABLISHED)
 467                 {
 468                         sock->state=SS_CONNECTED;
 469                         return 0;
 470                 }
 471                 if(sock->state==SS_CONNECTING && sk->state == TCP_CLOSE)
 472                 {
 473                         sock->state=SS_UNCONNECTED;
 474                         return -ECONNREFUSED;
 475                 }
 476                 if(sock->state!=SS_CONNECTING)
 477                         return -EISCONN;
 478                 if(flags&O_NONBLOCK)
 479                         return -EALREADY;
 480                 /*
 481                  *      Drop through the connect up logic to the wait.
 482                  */
 483         }
 484         
 485         if(addr_len < sizeof(sunaddr->sun_family)+1 || sunaddr->sun_family!=AF_UNIX)
 486                 return -EINVAL;
 487                 
 488         unix_mkname(sunaddr, addr_len);
 489                 
 490         if(sk->type==SOCK_DGRAM)
 491         {
 492                 if(sk->protinfo.af_unix.other)
 493                 {
 494                         sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
 495                         sk->protinfo.af_unix.other=NULL;
 496                         sock->state=SS_UNCONNECTED;
 497                 }
 498                 other=unix_find_other(sunaddr->sun_path, &err);
 499                 if(other==NULL)
 500                         return err;
 501                 if(other->type!=sk->type)
 502                         return -EPROTOTYPE;
 503                 other->protinfo.af_unix.locks++;
 504                 sk->protinfo.af_unix.other=other;
 505                 sock->state=SS_CONNECTED;
 506                 sk->state=TCP_ESTABLISHED;
 507                 return 0;                       /* Done */
 508         }
 509         
 510 
 511         if(sock->state==SS_UNCONNECTED)
 512         {
 513                 /*
 514                  *      Now ready to connect
 515                  */
 516          
 517                 skb=sock_alloc_send_skb(sk, 0, 0, 0, &err); /* Marker object */
 518                 if(skb==NULL)
 519                         return err;
 520                 skb->sk=sk;                             /* So they know it is us */
 521                 skb->free=1;
 522                 sk->state=TCP_CLOSE;
 523                 unix_mkname(sunaddr, addr_len);
 524                 other=unix_find_other(sunaddr->sun_path, &err);
 525                 if(other==NULL)
 526                 {
 527                         kfree_skb(skb, FREE_WRITE);
 528                         return err;
 529                 }
 530                 if(other->type!=sk->type)
 531                 {
 532                         kfree_skb(skb, FREE_WRITE);
 533                         return -EPROTOTYPE;
 534                 }
 535                 other->protinfo.af_unix.locks++;                /* Lock the other socket so it doesn't run off for a moment */
 536                 other->ack_backlog++;
 537                 sk->protinfo.af_unix.other=other;
 538                 skb_queue_tail(&other->receive_queue,skb);
 539                 sk->state=TCP_SYN_SENT;
 540                 sock->state=SS_CONNECTING;
 541                 sti();
 542                 other->data_ready(other,0);             /* Wake up ! */         
 543         }
 544                         
 545         
 546         /* Wait for an accept */
 547         
 548         cli();
 549         while(sk->state==TCP_SYN_SENT)
 550         {
 551                 if(flags&O_NONBLOCK)
 552                 {
 553                         sti();
 554                         return -EINPROGRESS;
 555                 }
 556                 interruptible_sleep_on(sk->sleep);
 557                 if(current->signal & ~current->blocked)
 558                 {
 559                         sti();
 560                         return -ERESTARTSYS;
 561                 }
 562         }
 563         
 564         /*
 565          *      Has the other end closed on us ?
 566          */
 567          
 568         if(sk->state==TCP_CLOSE)
 569         {
 570                 sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
 571                 sk->protinfo.af_unix.other=NULL;
 572                 sock->state=SS_UNCONNECTED;
 573                 sti();
 574                 return -ECONNREFUSED;
 575         }
 576         
 577         /*
 578          *      Amazingly it has worked
 579          */
 580          
 581         sock->state=SS_CONNECTED;
 582         sti();
 583         return 0;
 584         
 585 }
 586 
 587 static int unix_socketpair(struct socket *a, struct socket *b)
     /* [previous][next][first][last][top][bottom][index][help] */
 588 {
 589         unix_socket *ska,*skb;  
 590         
 591         ska=a->data;
 592         skb=b->data;
 593 
 594         /* Join our sockets back to back */
 595         ska->protinfo.af_unix.locks++;
 596         skb->protinfo.af_unix.locks++;
 597         ska->protinfo.af_unix.other=skb;
 598         skb->protinfo.af_unix.other=ska;
 599         ska->state=TCP_ESTABLISHED;
 600         skb->state=TCP_ESTABLISHED;
 601         return 0;
 602 }
 603 
 604 static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 605 {
 606         unix_socket *sk=sock->data;
 607         unix_socket *newsk, *tsk;
 608         struct sk_buff *skb;
 609         
 610         if(sk->type!=SOCK_STREAM)
 611         {
 612                 return -EOPNOTSUPP;
 613         }
 614         if(sk->state!=TCP_LISTEN)
 615         {
 616                 return -EINVAL;
 617         }
 618                 
 619         newsk=newsock->data;
 620         if(sk->protinfo.af_unix.name!=NULL)
 621         {
 622                 newsk->protinfo.af_unix.name=kmalloc(strlen(sk->protinfo.af_unix.name)+1, GFP_KERNEL);
 623                 if(newsk->protinfo.af_unix.name==NULL)
 624                         return -ENOMEM;
 625                 strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
 626         }
 627                 
 628         do
 629         {
 630                 cli();
 631                 skb=skb_dequeue(&sk->receive_queue);
 632                 if(skb==NULL)
 633                 {
 634                         if(flags&O_NONBLOCK)
 635                         {
 636                                 sti();
 637                                 return -EAGAIN;
 638                         }
 639                         interruptible_sleep_on(sk->sleep);
 640                         if(current->signal & ~current->blocked)
 641                         {
 642                                 sti();
 643                                 return -ERESTARTSYS;
 644                         }
 645                         sti();
 646                 }
 647         }
 648         while(skb==NULL);
 649         tsk=skb->sk;
 650         kfree_skb(skb, FREE_WRITE);     /* The buffer is just used as a tag */
 651         sk->ack_backlog--;
 652         newsk->protinfo.af_unix.other=tsk;
 653         tsk->protinfo.af_unix.other=newsk;
 654         tsk->state=TCP_ESTABLISHED;
 655         newsk->state=TCP_ESTABLISHED;
 656         newsk->protinfo.af_unix.locks++;        /* Swap lock over */
 657         sk->protinfo.af_unix.locks--;   /* Locked to child socket not master */
 658         tsk->protinfo.af_unix.locks++;  /* Back lock */
 659         sti();
 660         tsk->state_change(tsk);         /* Wake up any sleeping connect */
 661         sock_wake_async(tsk->socket, 0);
 662         return 0;
 663 }
 664 
 665 static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 666 {
 667         unix_socket *sk=sock->data;
 668         struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
 669         
 670         if(peer)
 671         {
 672                 if(sk->protinfo.af_unix.other==NULL)
 673                         return -ENOTCONN;
 674                 sk=sk->protinfo.af_unix.other;
 675         }
 676         sunaddr->sun_family=AF_UNIX;
 677         if(sk->protinfo.af_unix.name==NULL)
 678         {
 679                 *sunaddr->sun_path=0;
 680                 *uaddr_len=sizeof(sunaddr->sun_family)+1;
 681                 return 0;               /* Not bound */
 682         }
 683         *uaddr_len=sizeof(sunaddr->sun_family)+strlen(sk->protinfo.af_unix.name)+1;
 684         strcpy(sunaddr->sun_path,sk->protinfo.af_unix.name);            /* 108 byte limited */
 685         return 0;
 686 }
 687 
 688 /*
 689  *      Support routines for struct cmsghdr handling
 690  */
 691  
 692 static struct cmsghdr *unix_copyrights(void *userp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 693 {
 694         struct cmsghdr *cm;
 695 
 696         if(len>256|| len <=0)
 697                 return NULL;
 698         cm=kmalloc(len, GFP_KERNEL);
 699         memcpy_fromfs(cm, userp, len);
 700         return cm;
 701 }
 702 
 703 /*
 704  *      Return a header block
 705  */
 706  
 707 static void unix_returnrights(void *userp, int len, struct cmsghdr *cm)
     /* [previous][next][first][last][top][bottom][index][help] */
 708 {
 709         memcpy_tofs(userp, cm, len);
 710         kfree(cm);
 711 }
 712 
 713 /*
 714  *      Copy file descriptors into system space.
 715  *      Return number copied or negative error code
 716  */
 717  
 718 static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp)
     /* [previous][next][first][last][top][bottom][index][help] */
 719 {
 720         int num=cmsg->cmsg_len-sizeof(struct cmsghdr);
 721         int i;
 722         int *fdp=(int *)cmsg->cmsg_data;
 723         num/=4; /* Odd bytes are forgotten in BSD not errored */
 724         
 725 
 726         if(num>=UNIX_MAX_FD)
 727                 return -EINVAL;
 728         
 729         /*
 730          *      Verify the descriptors.
 731          */
 732          
 733         for(i=0; i< num; i++)
 734         {
 735                 int fd;
 736                 
 737                 fd = fdp[i];    
 738 #if 0
 739                 printk("testing  fd %d\n", fd);
 740 #endif
 741                 if(fd < 0|| fd >=NR_OPEN)
 742                         return -EBADF;
 743                 if(current->files->fd[fd]==NULL)
 744                         return -EBADF;
 745         }
 746         
 747         /*
 748          *      Make sure the garbage collector can cope.
 749          */
 750          
 751         if(unix_gc_free<num)
 752                 return -ENOBUFS;
 753         
 754         /* add another reference to these files */
 755         for(i=0; i< num; i++)
 756         {
 757                 fp[i]=current->files->fd[fdp[i]];
 758                 fp[i]->f_count++;
 759                 unix_gc_add(sk, fp[i]);
 760         }
 761         
 762         return num;
 763 }
 764 
 765 /*
 766  *      Free the descriptors in the array
 767  */
 768 
 769 static void unix_fd_free(struct sock *sk, struct file **fp, int num)
     /* [previous][next][first][last][top][bottom][index][help] */
 770 {
 771         int i;
 772         for(i=0;i<num;i++)
 773         {
 774                 close_fp(fp[i]);
 775                 unix_gc_remove(fp[i]);
 776         }
 777 }
 778 
 779 /*
 780  *      Count the free descriptors available to a process. 
 781  *      Interpretation issue: Is the limit the highest descriptor (buggy
 782  *      allowing passed fd's higher up to cause a limit to be exceeded) -
 783  *      but how the old code did it - or like this...
 784  */
 785 
 786 static int unix_files_free(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 787 {
 788         int i;
 789         int n=0;
 790         for (i=0;i<NR_OPEN;i++)
 791         {
 792                 if(current->files->fd[i])
 793                         n++;
 794         }
 795         
 796         i=NR_OPEN;
 797         if(i>current->rlim[RLIMIT_NOFILE].rlim_cur)
 798                 i=current->rlim[RLIMIT_NOFILE].rlim_cur;
 799         if(n>=i)
 800                 return 0;
 801         return i-n;
 802 }
 803 
 804 /*
 805  *      Perform the AF_UNIX file descriptor pass out functionality. This
 806  *      is nasty and messy as is the whole design of BSD file passing.
 807  */
 808 
 809 static void unix_detach_fds(struct sk_buff *skb, struct cmsghdr *cmsg)
     /* [previous][next][first][last][top][bottom][index][help] */
 810 {
 811         int i;
 812         /* count of space in parent for fds */
 813         int cmnum;
 814         struct file **fp;
 815         struct file **ufp;
 816         int *cmfptr=NULL;       /* =NULL To keep gcc happy */
 817         /* number of fds actually passed */
 818         int fdnum;
 819         int ffree;
 820         int ufn=0;
 821 
 822         if(cmsg==NULL)
 823                 cmnum=0;
 824         else
 825         {
 826                 cmnum=cmsg->cmsg_len-sizeof(struct cmsghdr);
 827                 cmnum/=sizeof(int);
 828                 cmfptr=(int *)&cmsg->cmsg_data;
 829         }
 830         
 831         memcpy(&fdnum,skb->h.filp,sizeof(int));
 832         fp=(struct file **)(skb->h.filp+sizeof(int));
 833         if(cmnum>fdnum)
 834                 cmnum=fdnum;
 835         ffree=unix_files_free();
 836         if(cmnum>ffree)
 837                 cmnum=ffree;
 838         ufp=&current->files->fd[0];
 839         
 840         /*
 841          *      Copy those that fit
 842          */
 843         for(i=0;i<cmnum;i++)
 844         {
 845                 /*
 846                  *      Insert the fd
 847                  */
 848                 while(ufp[ufn]!=NULL)
 849                         ufn++;
 850                 ufp[ufn]=fp[i];
 851                 *cmfptr++=ufn;
 852                 FD_CLR(ufn,&current->files->close_on_exec);
 853                 unix_gc_remove(fp[i]);
 854         }
 855         /*
 856          *      Dump those that don't
 857          */
 858         for(;i<fdnum;i++)
 859         {
 860                 close_fp(fp[i]);
 861                 unix_gc_remove(fp[i]);
 862         }
 863         kfree(skb->h.filp);
 864         skb->h.filp=NULL;
 865 
 866         /* no need to use destructor */
 867         skb->destructor = NULL;
 868 }
 869 
 870 static void unix_destruct_fds(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 871 {
 872         unix_detach_fds(skb,NULL);
 873 }
 874         
 875 /*
 876  *      Attach the file descriptor array to an sk_buff
 877  */
 878 static void unix_attach_fds(int fpnum,struct file **fp,struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 879 {
 880 
 881         skb->h.filp=kmalloc(sizeof(int)+fpnum*sizeof(struct file *), 
 882                                                         GFP_KERNEL);
 883         /* number of descriptors starts block */
 884         memcpy(skb->h.filp,&fpnum,sizeof(int));
 885         /* actual  descriptors */
 886         memcpy(skb->h.filp+sizeof(int),fp,fpnum*sizeof(struct file *));
 887         skb->destructor = unix_destruct_fds;
 888 }
 889 
 890 /*
 891  *      Send AF_UNIX data.
 892  */
 893                 
 894 static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 895 {
 896         unix_socket *sk=sock->data;
 897         unix_socket *other;
 898         struct sockaddr_un *sunaddr=msg->msg_name;
 899         int err,size;
 900         struct sk_buff *skb;
 901         int limit=0;
 902         int sent=0;
 903         struct file *fp[UNIX_MAX_FD];
 904         /* number of fds waiting to be passed, 0 means either
 905          * no fds to pass or they've already been passed 
 906          */
 907         int fpnum=0;
 908 
 909         if(sk->err)
 910                 return sock_error(sk);
 911 
 912         if(flags&MSG_OOB)
 913                 return -EOPNOTSUPP;
 914                         
 915         if(flags)       /* For now */ {
 916                 return -EINVAL;
 917         }
 918                 
 919         if(sunaddr!=NULL)
 920         {
 921                 if(sock->type==SOCK_STREAM)
 922                 {
 923                         if(sk->state==TCP_ESTABLISHED)
 924                                 return -EISCONN;
 925                         else
 926                                 return -EOPNOTSUPP;
 927                 }
 928         }
 929 
 930         if(sunaddr==NULL)
 931         {
 932                 if(sk->protinfo.af_unix.other==NULL)
 933                         return -ENOTCONN;
 934         }
 935 
 936         /*
 937          *      A control message has been attached.
 938          */
 939         if(msg->msg_accrights) 
 940         {
 941                 struct cmsghdr *cm=unix_copyrights(msg->msg_accrights, 
 942                                                 msg->msg_accrightslen);
 943                 if(cm==NULL || msg->msg_accrightslen<sizeof(struct cmsghdr) ||
 944                    cm->cmsg_type!=SCM_RIGHTS ||
 945                    cm->cmsg_level!=SOL_SOCKET ||
 946                    msg->msg_accrightslen!=cm->cmsg_len)
 947                 {
 948                         kfree(cm);
 949                         return -EINVAL;
 950                 }
 951                 fpnum=unix_fd_copy(sk,cm,fp);
 952                 kfree(cm);
 953                 if(fpnum<0) {
 954                         return fpnum;
 955                 }
 956         }
 957 
 958         while(sent < len)
 959         {
 960                 /*
 961                  *      Optimisation for the fact that under 0.01% of X messages typically
 962                  *      need breaking up.
 963                  */
 964                  
 965                 size=len-sent;
 966 
 967                 if(size>(sk->sndbuf-sizeof(struct sk_buff))/2)  /* Keep two messages in the pipe so it schedules better */
 968                 {
 969                         if(sock->type==SOCK_DGRAM)
 970                         {
 971                                 unix_fd_free(sk,fp,fpnum);
 972                                 return -EMSGSIZE;
 973                         }
 974                         size=(sk->sndbuf-sizeof(struct sk_buff))/2;
 975                 }
 976                 /*
 977                  *      Keep to page sized kmalloc()'s as various people
 978                  *      have suggested. Big mallocs stress the vm too
 979                  *      much.
 980                  */
 981 
 982                 if(size > 4000 && sock->type!=SOCK_DGRAM)
 983                         limit = 4000;   /* Fall back to 4K if we can't grab a big buffer this instant */
 984                 else
 985                         limit = 0;      /* Otherwise just grab and wait */
 986 
 987                 /*
 988                  *      Grab a buffer
 989                  */
 990                  
 991                 skb=sock_alloc_send_skb(sk,size,limit,nonblock, &err);
 992                 
 993                 if(skb==NULL)
 994                 {
 995                         unix_fd_free(sk,fp,fpnum);
 996                         if(sent)
 997                         {
 998                                 sk->err=-err;
 999                                 return sent;
1000                         }
1001                         return err;
1002                 }
1003                 size=skb_tailroom(skb);         /* If we dropped back on a limit then our skb is smaller */
1004 
1005                 skb->sk=sk;
1006                 skb->free=1;
1007                 
1008                 if(fpnum)
1009                 {
1010                         unix_attach_fds(fpnum,fp,skb);
1011                         fpnum=0;
1012                 }
1013                 else
1014                         skb->h.filp=NULL;
1015 
1016                 memcpy_fromiovec(skb_put(skb,size),msg->msg_iov, size);
1017 
1018                 cli();
1019                 if(sunaddr==NULL)
1020                 {
1021                         other=sk->protinfo.af_unix.other;
1022                         if(sock->type==SOCK_DGRAM && other->dead)
1023                         {
1024                                 other->protinfo.af_unix.locks--;
1025                                 sk->protinfo.af_unix.other=NULL;
1026                                 sock->state=SS_UNCONNECTED;
1027                                 sti();
1028                                 kfree_skb(skb, FREE_WRITE);
1029                                 if(!sent)
1030                                         return -ECONNRESET;
1031                                 else
1032                                         return sent;
1033                         }
1034                 }
1035                 else
1036                 {
1037                         unix_mkname(sunaddr, msg->msg_namelen);
1038                         other=unix_find_other(sunaddr->sun_path, &err);
1039                         if(other==NULL)
1040                         {
1041                                 sti();
1042                                 kfree_skb(skb, FREE_WRITE);
1043                                 if(sent)
1044                                         return sent;
1045                                 else
1046                                         return err;
1047                         }
1048                 }
1049                 skb_queue_tail(&other->receive_queue, skb);
1050                 sti();
1051                 /* if we sent an fd, only do it once */
1052                 other->data_ready(other,size);
1053                 sent+=size;
1054         }
1055         return sent;
1056 }
1057 
1058 /*
1059  *      Sleep until data has arrive. But check for races..
1060  */
1061  
1062 static void unix_data_wait(unix_socket * sk)
     /* [previous][next][first][last][top][bottom][index][help] */
1063 {
1064         cli();
1065         if (!skb_peek(&sk->receive_queue)) {
1066                 sk->socket->flags |= SO_WAITDATA;
1067                 interruptible_sleep_on(sk->sleep);
1068                 sk->socket->flags &= ~SO_WAITDATA;
1069         }
1070         sti();
1071 }
1072 
1073 static int unix_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
1074 {
1075         unix_socket *sk=sock->data;
1076         struct sockaddr_un *sunaddr=msg->msg_name;
1077         struct sk_buff *skb;
1078         int copied=0;
1079         unsigned char *sp;
1080         int len;
1081         int num;
1082         struct iovec *iov=msg->msg_iov;
1083         struct cmsghdr *cm=NULL;
1084         int ct=msg->msg_iovlen;
1085 
1086         if(flags&MSG_OOB)
1087                 return -EOPNOTSUPP;
1088                 
1089         if(addr_len)
1090                 *addr_len=0;
1091                 
1092         if(sk->err)
1093                 return sock_error(sk);
1094 
1095         if(msg->msg_accrights) 
1096         {
1097                 cm=unix_copyrights(msg->msg_accrights, 
1098                         msg->msg_accrightslen);
1099                 if(msg->msg_accrightslen<sizeof(struct cmsghdr)
1100 #if 0 
1101 /*              investigate this furthur -- Stevens example doen't seem to care */
1102                 ||
1103                    cm->cmsg_type!=SCM_RIGHTS ||
1104                    cm->cmsg_level!=SOL_SOCKET ||
1105                    msg->msg_accrightslen!=cm->cmsg_len
1106 #endif
1107                 )
1108                 {
1109                         kfree(cm);
1110                         printk("recvmsg: Bad msg_accrights\n");
1111                         return -EINVAL;
1112                 }
1113         }
1114         
1115         down(&sk->protinfo.af_unix.readsem);            /* Lock the socket */
1116         while(ct--)
1117         {
1118                 int done=0;
1119                 sp=iov->iov_base;
1120                 len=iov->iov_len;
1121                 iov++;
1122                 
1123                 while(done<len)
1124                 {
1125                         if (copied && (flags & MSG_PEEK))
1126                                 goto out;
1127                         if (copied == size)
1128                                 goto out;
1129                         skb=skb_dequeue(&sk->receive_queue);
1130                         if(skb==NULL)
1131                         {
1132                                 up(&sk->protinfo.af_unix.readsem);
1133                                 if(sk->shutdown & RCV_SHUTDOWN)
1134                                         return copied;
1135                                 if(copied)
1136                                         return copied;
1137                                 if(noblock)
1138                                         return -EAGAIN;
1139                                 if(current->signal & ~current->blocked)
1140                                         return -ERESTARTSYS;
1141                                 unix_data_wait(sk);
1142                                 down(&sk->protinfo.af_unix.readsem);
1143                                 continue;
1144                         }
1145                         if(msg->msg_name!=NULL)
1146                         {
1147                                 sunaddr->sun_family=AF_UNIX;
1148                                 if(skb->sk->protinfo.af_unix.name)
1149                                 {
1150                                         memcpy(sunaddr->sun_path, skb->sk->protinfo.af_unix.name, 108);
1151                                         if(addr_len)
1152                                                 *addr_len=strlen(sunaddr->sun_path)+sizeof(short);
1153                                 }
1154                                 else
1155                                         if(addr_len)
1156                                                 *addr_len=sizeof(short);
1157                         }
1158 
1159                         num=min(skb->len,size-copied);
1160                         memcpy_tofs(sp, skb->data, num);
1161 
1162                         if (skb->h.filp!=NULL)
1163                                 unix_detach_fds(skb,cm);
1164 
1165                         copied+=num;
1166                         done+=num;
1167                         sp+=num;
1168                         if (!(flags & MSG_PEEK))
1169                                 skb_pull(skb, num);
1170                         /* put the skb back if we didn't use it up.. */
1171                         if (skb->len) {
1172                                 skb_queue_head(&sk->receive_queue, skb);
1173                                 continue;
1174                         }
1175                         kfree_skb(skb, FREE_WRITE);
1176                         if(sock->type==SOCK_DGRAM || cm)
1177                                 goto out;
1178                 }
1179         }
1180 out:
1181         up(&sk->protinfo.af_unix.readsem);
1182         if(cm)
1183                 unix_returnrights(msg->msg_accrights,msg->msg_accrightslen,cm);
1184         return copied;
1185 }
1186 
1187 static int unix_shutdown(struct socket *sock, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
1188 {
1189         unix_socket *sk=(unix_socket *)sock->data;
1190         unix_socket *other=sk->protinfo.af_unix.other;
1191         if(mode&SEND_SHUTDOWN)
1192         {
1193                 sk->shutdown|=SEND_SHUTDOWN;
1194                 sk->state_change(sk);
1195                 if(other)
1196                 {
1197                         other->shutdown|=RCV_SHUTDOWN;
1198                         other->state_change(other);
1199                 }
1200         }
1201         other=sk->protinfo.af_unix.other;
1202         if(mode&RCV_SHUTDOWN)
1203         {
1204                 sk->shutdown|=RCV_SHUTDOWN;
1205                 sk->state_change(sk);
1206                 if(other)
1207                 {
1208                         other->shutdown|=SEND_SHUTDOWN;
1209                         other->state_change(other);
1210                 }
1211         }
1212         return 0;
1213 }
1214 
1215                 
1216 static int unix_select(struct socket *sock,  int sel_type, select_table *wait)
     /* [previous][next][first][last][top][bottom][index][help] */
1217 {
1218         return datagram_select(sock->data,sel_type,wait);
1219 }
1220 
1221 static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1222 {
1223         unix_socket *sk=sock->data;
1224         int err;
1225         long amount=0;
1226                         
1227         switch(cmd)
1228         {
1229         
1230                 case TIOCOUTQ:
1231                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1232                         if(err)
1233                                 return err;
1234                         amount=sk->sndbuf-sk->wmem_alloc;
1235                         if(amount<0)
1236                                 amount=0;
1237                         put_fs_long(amount,(unsigned long *)arg);
1238                         return 0;
1239                 case TIOCINQ:
1240                 {
1241                         struct sk_buff *skb;
1242                         if(sk->state==TCP_LISTEN)
1243                                 return -EINVAL;
1244                         /* These two are safe on a single CPU system as only user tasks fiddle here */
1245                         if((skb=skb_peek(&sk->receive_queue))!=NULL)
1246                                 amount=skb->len;
1247                         err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
1248                         put_fs_long(amount,(unsigned long *)arg);
1249                         return 0;
1250                 }
1251 
1252                 default:
1253                         return -EINVAL;
1254         }
1255         /*NOTREACHED*/
1256         return(0);
1257 }
1258 
1259 #ifdef CONFIG_PROC_FS
1260 static int unix_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
1261 {
1262         off_t pos=0;
1263         off_t begin=0;
1264         int len=0;
1265         unix_socket *s=unix_socket_list;
1266         
1267         len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St Path\n");
1268         
1269         while(s!=NULL)
1270         {
1271                 len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
1272                         s,
1273                         s->protinfo.af_unix.locks,
1274                         0,
1275                         s->socket->flags,
1276                         s->socket->type,
1277                         s->socket->state);
1278                 if(s->protinfo.af_unix.name!=NULL)
1279                         len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name);
1280                 else
1281                         buffer[len++]='\n';
1282                 
1283                 pos=begin+len;
1284                 if(pos<offset)
1285                 {
1286                         len=0;
1287                         begin=pos;
1288                 }
1289                 if(pos>offset+length)
1290                         break;
1291                 s=s->next;
1292         }
1293         *start=buffer+(offset-begin);
1294         len-=(offset-begin);
1295         if(len>length)
1296                 len=length;
1297         return len;
1298 }
1299 #endif
1300 
1301 static struct proto_ops unix_proto_ops = {
1302         AF_UNIX,
1303         
1304         unix_create,
1305         unix_dup,
1306         unix_release,
1307         unix_bind,
1308         unix_connect,
1309         unix_socketpair,
1310         unix_accept,
1311         unix_getname,
1312         unix_select,
1313         unix_ioctl,
1314         unix_listen,
1315         unix_shutdown,
1316         unix_setsockopt,
1317         unix_getsockopt,
1318         unix_fcntl,
1319         unix_sendmsg,
1320         unix_recvmsg
1321 };
1322 
1323 
1324 void unix_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
1325 {
1326         printk("NET3: Unix domain sockets 0.12 for Linux NET3.033.\n");
1327         sock_register(unix_proto_ops.family, &unix_proto_ops);
1328 #ifdef CONFIG_PROC_FS
1329         proc_net_register(&(struct proc_dir_entry) {
1330                 PROC_NET_UNIX,  4, "unix",
1331                 S_IFREG | S_IRUGO, 1, 0, 0,
1332                 0, &proc_net_inode_operations,
1333                 unix_get_info
1334         });
1335 #endif
1336 }
1337 /*
1338  * Local variables:
1339  *  compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c"
1340  * End:
1341  */

/* [previous][next][first][last][top][bottom][index][help] */