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

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