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

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