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

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