root/net/unix/sock.c

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

DEFINITIONS

This source file includes following definitions.
  1. min
  2. unix_lock
  3. unix_unlock
  4. unix_proto_listen
  5. unix_proto_setsockopt
  6. unix_proto_getsockopt
  7. unix_proto_sendto
  8. unix_proto_recvfrom
  9. unix_proto_shutdown
  10. unix_proto_send
  11. unix_proto_recv
  12. unix_data_lookup
  13. unix_data_alloc
  14. unix_data_ref
  15. unix_data_deref
  16. unix_proto_create
  17. unix_proto_dup
  18. unix_proto_release
  19. unix_proto_bind
  20. unix_proto_connect
  21. unix_proto_socketpair
  22. unix_proto_accept
  23. unix_proto_getname
  24. unix_proto_read
  25. unix_proto_write
  26. unix_proto_select
  27. unix_proto_ioctl
  28. unix_proto_init

   1 /*
   2  * UNIX         An implementation of the AF_UNIX network domain for the
   3  *              LINUX operating system.  UNIX is implemented using the
   4  *              BSD Socket interface as the means of communication with
   5  *              the user level.
   6  *
   7  * Version:     @(#)sock.c      1.0.5   05/25/93
   8  *
   9  * Authors:     Orest Zborowski, <obz@Kodak.COM>
  10  *              Ross Biro, <bir7@leland.Stanford.Edu>
  11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12  *
  13  * Fixes:
  14  *              Alan Cox        :       Verify Area
  15  *              NET2E Team      :       Page fault locks
  16  *      Dmitry Gorodchanin      :       /proc locking
  17  *
  18  * To Do:
  19  *      Some nice person is looking into Unix sockets done properly. NET3
  20  *      will replace all of this and include datagram sockets and socket
  21  *      options - so please stop asking me for them 8-)
  22  *
  23  *
  24  *              This program is free software; you can redistribute it and/or
  25  *              modify it under the terms of the GNU General Public License
  26  *              as published by the Free Software Foundation; either version
  27  *              2 of the License, or(at your option) any later version.
  28  */
  29 
  30 #include <linux/kernel.h>
  31 #include <linux/major.h>
  32 #include <linux/signal.h>
  33 #include <linux/sched.h>
  34 #include <linux/errno.h>
  35 #include <linux/string.h>
  36 #include <linux/stat.h>
  37 #include <linux/socket.h>
  38 #include <linux/un.h>
  39 #include <linux/fcntl.h>
  40 #include <linux/termios.h>
  41 #include <linux/sockios.h>
  42 #include <linux/net.h>
  43 #include <linux/fs.h>
  44 #include <linux/malloc.h>
  45 
  46 #include <asm/system.h>
  47 #include <asm/segment.h>
  48 
  49 #include <stdarg.h>
  50 
  51 #include "unix.h"
  52 
  53 /*
  54  *      Because these have the address in them they casually waste an extra 8K of kernel data
  55  *      space that need not be wasted.
  56  */
  57  
  58 struct unix_proto_data unix_datas[NSOCKETS];
  59 
  60 static int unix_proto_create(struct socket *sock, int protocol);
  61 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock);
  62 static int unix_proto_release(struct socket *sock, struct socket *peer);
  63 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
  64                            int sockaddr_len);
  65 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
  66                               int sockaddr_len, int flags);
  67 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2);
  68 static int unix_proto_accept(struct socket *sock, struct socket *newsock, 
  69                              int flags);
  70 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
  71                               int *usockaddr_len, int peer);
  72 static int unix_proto_read(struct socket *sock, char *ubuf, int size,
  73                            int nonblock);
  74 static int unix_proto_write(struct socket *sock, char *ubuf, int size,
  75                             int nonblock);
  76 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait);
  77 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd,
  78                             unsigned long arg);
  79 static int unix_proto_listen(struct socket *sock, int backlog);
  80 static int unix_proto_send(struct socket *sock, void *buff, int len,
  81                             int nonblock, unsigned flags);
  82 static int unix_proto_recv(struct socket *sock, void *buff, int len,
  83                             int nonblock, unsigned flags);
  84 static int unix_proto_sendto(struct socket *sock, void *buff, int len,
  85                               int nonblock, unsigned flags,
  86                               struct sockaddr *addr, int addr_len);
  87 static int unix_proto_recvfrom(struct socket *sock, void *buff, int len,
  88                                 int nonblock, unsigned flags,
  89                                 struct sockaddr *addr, int *addr_len);
  90 
  91 static int unix_proto_shutdown(struct socket *sock, int how);
  92 
  93 static int unix_proto_setsockopt(struct socket *sock, int level, int optname,
  94                                   char *optval, int optlen);
  95 static int unix_proto_getsockopt(struct socket *sock, int level, int optname,
  96                                   char *optval, int *optlen);
  97 
  98 
  99 static inline int min(int a, int b)
     /* [previous][next][first][last][top][bottom][index][help] */
 100 {
 101         if (a < b)
 102                 return(a);
 103         return(b);
 104 }
 105 
 106 
 107 
 108 /* Support routines doing anti page fault locking 
 109  * FvK & Matt Dillon (borrowed From NET2E3)
 110  */
 111 
 112 /*
 113  * Locking for unix-domain sockets.  We don't use the socket structure's
 114  * wait queue because it is allowed to 'go away' outside of our control,
 115  * whereas unix_proto_data structures stick around.
 116  */
 117  
 118 static void unix_lock(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120         while (upd->lock_flag)
 121                 sleep_on(&upd->wait);
 122         upd->lock_flag = 1;
 123 }
 124 
 125 
 126 static void unix_unlock(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         upd->lock_flag = 0;
 129         wake_up(&upd->wait);
 130 }
 131 
 132 /*
 133  *      We don't have to do anything. 
 134  */
 135  
 136 static int unix_proto_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 137 {
 138         return(0);
 139 }
 140 
 141 /*
 142  *      Until the new NET3 Unix code is done we have no options.
 143  */
 144 
 145 static int unix_proto_setsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 146                       char *optval, int optlen)
 147 {
 148         return(-EOPNOTSUPP);
 149 }
 150 
 151 
 152 static int unix_proto_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 153                       char *optval, int *optlen)
 154 {
 155         return(-EOPNOTSUPP);
 156 }
 157 
 158 
 159 /*
 160  *      SendTo() doesn't matter as we also have no Datagram support!
 161  */
 162 
 163 static int unix_proto_sendto(struct socket *sock, void *buff, int len, int nonblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
 164                   unsigned flags,  struct sockaddr *addr, int addr_len)
 165 {
 166         return(-EOPNOTSUPP);
 167 }     
 168 
 169 static int unix_proto_recvfrom(struct socket *sock, void *buff, int len, int nonblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
 170                     unsigned flags, struct sockaddr *addr, int *addr_len)
 171 {
 172         return(-EOPNOTSUPP);
 173 }     
 174 
 175 /*
 176  *      You can't shutdown a unix domain socket.
 177  */
 178 
 179 static int unix_proto_shutdown(struct socket *sock, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181         return(-EOPNOTSUPP);
 182 }
 183 
 184 
 185 /*
 186  *      Send data to a unix socket.
 187  */
 188  
 189 static int unix_proto_send(struct socket *sock, void *buff, int len, int nonblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 190                 unsigned flags)
 191 {
 192         if (flags != 0) 
 193                 return(-EINVAL);
 194         return(unix_proto_write(sock, (char *) buff, len, nonblock));
 195 }
 196 
 197 
 198 /* 
 199  *      Receive data. This version of AF_UNIX also lacks MSG_PEEK 8(
 200  */
 201  
 202 static int unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 203                 unsigned flags)
 204 {
 205         if (flags != 0) 
 206                 return(-EINVAL);
 207         return(unix_proto_read(sock, (char *) buff, len, nonblock));
 208 }
 209 
 210 /*
 211  *      Given an address and an inode go find a unix control structure
 212  */
 213  
 214 static struct unix_proto_data *
 215 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len,
     /* [previous][next][first][last][top][bottom][index][help] */
 216                  struct inode *inode)
 217 {
 218          struct unix_proto_data *upd;
 219 
 220          for(upd = unix_datas; upd <= last_unix_data; ++upd) 
 221          {
 222                 if (upd->refcnt > 0 && upd->socket &&
 223                         upd->socket->state == SS_UNCONNECTED &&
 224                         upd->sockaddr_un.sun_family == sockun->sun_family &&
 225                         upd->inode == inode) 
 226                         
 227                         return(upd);
 228         }
 229         return(NULL);
 230 }
 231 
 232 /*
 233  *      We allocate a page of data for the socket. This is woefully inadequate and helps cause vast
 234  *      amounts of excess task switching and blocking when transferring stuff like bitmaps via X.
 235  *      It doesn't help this problem that the Linux scheduler is desperately in need of a major 
 236  *      rewrite. Somewhere near 16K would be better maybe 32.
 237  */
 238 
 239 static struct unix_proto_data *
 240 unix_data_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 241 {
 242         struct unix_proto_data *upd;
 243 
 244         cli();
 245         for(upd = unix_datas; upd <= last_unix_data; ++upd) 
 246         {
 247                 if (!upd->refcnt) 
 248                 {
 249                         upd->refcnt = -1;       /* unix domain socket not yet initialised - bgm */
 250                         sti();
 251                         upd->socket = NULL;
 252                         upd->sockaddr_len = 0;
 253                         upd->sockaddr_un.sun_family = 0;
 254                         upd->buf = NULL;
 255                         upd->bp_head = upd->bp_tail = 0;
 256                         upd->inode = NULL;
 257                         upd->peerupd = NULL;
 258                         return(upd);
 259                 }
 260         }
 261         sti();
 262         return(NULL);
 263 }
 264 
 265 /*
 266  *      The data area is owned by all its users. Thus we need to track owners
 267  *      carefully and not free data at the wrong moment. These look like they need
 268  *      interrupt protection but they don't because no interrupt ever fiddles with
 269  *      these counts. With an SMP Linux you'll need to protect these!
 270  */
 271 
 272 static inline void unix_data_ref(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 273 {
 274         if (!upd) 
 275         {
 276                 return;
 277         }
 278         ++upd->refcnt;
 279 }
 280 
 281 
 282 static void unix_data_deref(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 283 {
 284         if (!upd) 
 285         {
 286                 return;
 287         }
 288         if (upd->refcnt == 1) 
 289         {
 290                 if (upd->buf) 
 291                 {
 292                         free_page((unsigned long)upd->buf);
 293                         upd->buf = NULL;
 294                         upd->bp_head = upd->bp_tail = 0;
 295                 }
 296         }
 297         --upd->refcnt;
 298 }
 299 
 300 
 301 /*
 302  *      Upon a create, we allocate an empty protocol data,
 303  *      and grab a page to buffer writes.
 304  */
 305  
 306 static int unix_proto_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 307 {
 308         struct unix_proto_data *upd;
 309 
 310         /*
 311          *      No funny SOCK_RAW stuff
 312          */
 313          
 314         if (protocol != 0) 
 315         {
 316                 return(-EINVAL);
 317         }
 318 
 319         if (!(upd = unix_data_alloc())) 
 320         {
 321                 printk("UNIX: create: can't allocate buffer\n");
 322                 return(-ENOMEM);
 323         }
 324         if (!(upd->buf = (char*) get_free_page(GFP_USER))) 
 325         {
 326                 printk("UNIX: create: can't get page!\n");
 327                 unix_data_deref(upd);
 328                 return(-ENOMEM);
 329         }
 330         upd->protocol = protocol;
 331         upd->socket = sock;
 332         UN_DATA(sock) = upd;
 333         upd->refcnt = 1;        /* Now its complete - bgm */
 334         return(0);
 335 }
 336 
 337 /*
 338  *      Duplicate a socket.
 339  */
 340 
 341 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 342 {
 343         struct unix_proto_data *upd = UN_DATA(oldsock);
 344         return(unix_proto_create(newsock, upd->protocol));
 345 }
 346 
 347 
 348 /*
 349  *      Release a Unix domain socket.
 350  */
 351  
 352 static int unix_proto_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354         struct unix_proto_data *upd = UN_DATA(sock);
 355 
 356         if (!upd) 
 357                 return(0);
 358 
 359         if (upd->socket != sock) 
 360         {
 361                 printk("UNIX: release: socket link mismatch!\n");
 362                 return(-EINVAL);
 363         }
 364 
 365         if (upd->inode) 
 366         {
 367                 iput(upd->inode);
 368                 upd->inode = NULL;
 369         }
 370 
 371         UN_DATA(sock) = NULL;
 372         upd->socket = NULL;
 373 
 374         if (upd->peerupd)
 375                 unix_data_deref(upd->peerupd);
 376         unix_data_deref(upd);
 377         return(0);
 378 }
 379 
 380 
 381 /*
 382  *      Bind a name to a socket.
 383  *      This is where much of the work is done: we allocate a fresh page for
 384  *      the buffer, grab the appropriate inode and set things up.
 385  *
 386  *      FIXME: what should we do if an address is already bound?
 387  *        Here we return EINVAL, but it may be necessary to re-bind.
 388  *        I think thats what BSD does in the case of datagram sockets...
 389  */
 390  
 391 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 392                 int sockaddr_len)
 393 {
 394         char fname[UNIX_PATH_MAX + 1];
 395         struct unix_proto_data *upd = UN_DATA(sock);
 396         unsigned long old_fs;
 397         int i;
 398 
 399         if (sockaddr_len <= UN_PATH_OFFSET ||
 400                 sockaddr_len > sizeof(struct sockaddr_un)) 
 401         {
 402                 return(-EINVAL);
 403         }
 404         if (upd->sockaddr_len || upd->inode) 
 405         {
 406                 /*printk("UNIX: bind: already bound!\n");*/
 407                 return(-EINVAL);
 408         }
 409         memcpy(&upd->sockaddr_un, umyaddr, sockaddr_len);
 410         upd->sockaddr_un.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
 411         if (upd->sockaddr_un.sun_family != AF_UNIX) 
 412         {
 413                 return(-EINVAL);
 414         }
 415 
 416         memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
 417         fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
 418         old_fs = get_fs();
 419         set_fs(get_ds());
 420 
 421         i = do_mknod(fname, S_IFSOCK | S_IRWXUGO, 0);
 422 
 423         if (i == 0) 
 424                 i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
 425         set_fs(old_fs);
 426         if (i < 0) 
 427         {
 428 /*              printk("UNIX: bind: can't open socket %s\n", fname);*/
 429                 if(i==-EEXIST)
 430                         i=-EADDRINUSE;
 431                 return(i);
 432         }
 433         upd->sockaddr_len = sockaddr_len;       /* now its legal */
 434         
 435         return(0);
 436 }
 437 
 438 
 439 /*
 440  *      Perform a connection. we can only connect to unix sockets
 441  *      (I can't for the life of me find an application where that
 442  *      wouldn't be the case!)
 443  */
 444 
 445 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 446                    int sockaddr_len, int flags)
 447 {
 448         char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
 449         struct sockaddr_un sockun;
 450         struct unix_proto_data *serv_upd;
 451         struct inode *inode;
 452         unsigned long old_fs;
 453         int i;
 454 
 455         if (sockaddr_len <= UN_PATH_OFFSET ||
 456                 sockaddr_len > sizeof(struct sockaddr_un)) 
 457         {
 458                 return(-EINVAL);
 459         }
 460 
 461         if (sock->state == SS_CONNECTING) 
 462                 return(-EINPROGRESS);
 463         if (sock->state == SS_CONNECTED)
 464                 return(-EISCONN);
 465 
 466         memcpy(&sockun, uservaddr, sockaddr_len);
 467         sockun.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
 468         if (sockun.sun_family != AF_UNIX) 
 469         {
 470                 return(-EINVAL);
 471         }
 472 
 473 /*
 474  * Try to open the name in the filesystem - this is how we
 475  * identify ourselves and our server. Note that we don't
 476  * hold onto the inode that long, just enough to find our
 477  * server. When we're connected, we mooch off the server.
 478  */
 479 
 480         memcpy(fname, sockun.sun_path, sockaddr_len-UN_PATH_OFFSET);
 481         fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
 482         old_fs = get_fs();
 483         set_fs(get_ds());
 484         i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
 485         set_fs(old_fs);
 486         if (i < 0) 
 487         {
 488                 return(i);
 489         }
 490           
 491         serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
 492         iput(inode);
 493         if (!serv_upd) 
 494         {
 495                 return(-EINVAL);
 496         }
 497         
 498         if ((i = sock_awaitconn(sock, serv_upd->socket, flags)) < 0) 
 499         {
 500                 return(i);
 501         }
 502 
 503         if (sock->conn) 
 504         {
 505                 unix_data_ref(UN_DATA(sock->conn));
 506                 UN_DATA(sock)->peerupd = UN_DATA(sock->conn); /* ref server */
 507         }
 508         return(0);
 509 }
 510 
 511 
 512 /*
 513  *      To do a socketpair, we just connect the two datas, easy!
 514  *      Since we always wait on the socket inode, they're no contention
 515  *      for a wait area, and deadlock prevention in the case of a process
 516  *      writing to itself is, ignored, in true unix fashion!
 517  */
 518  
 519 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
 520 {
 521         struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
 522 
 523         unix_data_ref(upd1);
 524         unix_data_ref(upd2);
 525         upd1->peerupd = upd2;
 526         upd2->peerupd = upd1;
 527         return(0);
 528 }
 529 
 530 
 531 /* 
 532  *      On accept, we ref the peer's data for safe writes. 
 533  */
 534 
 535 static int unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 536 {
 537         struct socket *clientsock;
 538 
 539 /*
 540  * If there aren't any sockets awaiting connection,
 541  * then wait for one, unless nonblocking.
 542  */
 543 
 544         while(!(clientsock = sock->iconn)) 
 545         {
 546                 if (flags & O_NONBLOCK) 
 547                         return(-EAGAIN);
 548                 sock->flags |= SO_WAITDATA;
 549                 interruptible_sleep_on(sock->wait);
 550                 sock->flags &= ~SO_WAITDATA;
 551                 if (current->signal & ~current->blocked) 
 552                 {
 553                         return(-ERESTARTSYS);
 554                 }
 555         }
 556 /*
 557  * Great. Finish the connection relative to server and client,
 558  * wake up the client and return the new fd to the server.
 559  */
 560 
 561         sock->iconn = clientsock->next;
 562         clientsock->next = NULL;
 563         newsock->conn = clientsock;
 564         clientsock->conn = newsock;
 565         clientsock->state = SS_CONNECTED;
 566         newsock->state = SS_CONNECTED;
 567         unix_data_ref(UN_DATA(clientsock));
 568         UN_DATA(newsock)->peerupd            = UN_DATA(clientsock);
 569         UN_DATA(newsock)->sockaddr_un        = UN_DATA(sock)->sockaddr_un;
 570         UN_DATA(newsock)->sockaddr_len       = UN_DATA(sock)->sockaddr_len;
 571         wake_up_interruptible(clientsock->wait);
 572         sock_wake_async(clientsock, 0);
 573         return(0);
 574 }
 575 
 576 
 577 /*
 578  *      Gets the current name or the name of the connected socket. 
 579  */
 580  
 581 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 582                    int *usockaddr_len, int peer)
 583 {
 584         struct unix_proto_data *upd;
 585         int len;
 586 
 587         if (peer) 
 588         {
 589                 if (sock->state != SS_CONNECTED) 
 590                 {
 591                         return(-EINVAL);
 592                 }
 593                 upd = UN_DATA(sock->conn);
 594         }
 595         else
 596                 upd = UN_DATA(sock);
 597 
 598         len = upd->sockaddr_len;
 599         memcpy(usockaddr, &upd->sockaddr_un, len);
 600         *usockaddr_len=len;
 601         return(0);
 602 }
 603 
 604 
 605 /* 
 606  *      We read from our own buf. 
 607  */
 608  
 609 static int unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 610 {
 611         struct unix_proto_data *upd;
 612         int todo, avail;
 613 
 614         if ((todo = size) <= 0) 
 615                 return(0);
 616 
 617         upd = UN_DATA(sock);
 618         while(!(avail = UN_BUF_AVAIL(upd))) 
 619         {
 620                 if (sock->state != SS_CONNECTED) 
 621                 {
 622                         return((sock->state == SS_DISCONNECTING) ? 0 : -EINVAL);
 623                 }
 624                 if (nonblock) 
 625                         return(-EAGAIN);
 626                 sock->flags |= SO_WAITDATA;
 627                 interruptible_sleep_on(sock->wait);
 628                 sock->flags &= ~SO_WAITDATA;
 629                 if (current->signal & ~current->blocked) 
 630                 {
 631                         return(-ERESTARTSYS);
 632                 }
 633         }
 634 
 635 /*
 636  *      Copy from the read buffer into the user's buffer,
 637  *      watching for wraparound. Then we wake up the writer.
 638  */
 639    
 640         unix_lock(upd);
 641         do 
 642         {
 643                 int part, cando;
 644 
 645                 if (avail <= 0) 
 646                 {
 647                         printk("UNIX: read: AVAIL IS NEGATIVE!!!\n");
 648                         send_sig(SIGKILL, current, 1);
 649                         return(-EPIPE);
 650                 }
 651 
 652                 if ((cando = todo) > avail) 
 653                         cando = avail;
 654                 if (cando >(part = BUF_SIZE - upd->bp_tail)) 
 655                         cando = part;
 656                 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
 657                 upd->bp_tail =(upd->bp_tail + cando) &(BUF_SIZE-1);
 658                 ubuf += cando;
 659                 todo -= cando;
 660                 if (sock->state == SS_CONNECTED)
 661                 {
 662                         wake_up_interruptible(sock->conn->wait);
 663                         sock_wake_async(sock->conn, 2);
 664                 }
 665                 avail = UN_BUF_AVAIL(upd);
 666         } 
 667         while(todo && avail);
 668         unix_unlock(upd);
 669         return(size - todo);
 670 }
 671 
 672 
 673 /*
 674  *      We write to our peer's buf. When we connected we ref'd this
 675  *      peer so we are safe that the buffer remains, even after the
 676  *      peer has disconnected, which we check other ways.
 677  */
 678  
 679 static int unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 680 {
 681         struct unix_proto_data *pupd;
 682         int todo, space;
 683 
 684         if ((todo = size) <= 0)
 685                 return(0);
 686         if (sock->state != SS_CONNECTED) 
 687         {
 688                 if (sock->state == SS_DISCONNECTING) 
 689                 {
 690                         send_sig(SIGPIPE, current, 1);
 691                         return(-EPIPE);
 692                 }
 693                 return(-EINVAL);
 694         }
 695         pupd = UN_DATA(sock)->peerupd;  /* safer than sock->conn */
 696 
 697         while(!(space = UN_BUF_SPACE(pupd))) 
 698         {
 699                 sock->flags |= SO_NOSPACE;
 700                 if (nonblock) 
 701                         return(-EAGAIN);
 702                 sock->flags &= ~SO_NOSPACE;
 703                 interruptible_sleep_on(sock->wait);
 704                 if (current->signal & ~current->blocked) 
 705                 {
 706                         return(-ERESTARTSYS);
 707                 }
 708                 if (sock->state == SS_DISCONNECTING) 
 709                 {
 710                         send_sig(SIGPIPE, current, 1);
 711                         return(-EPIPE);
 712                 }
 713         }
 714 
 715 /*
 716  *      Copy from the user's buffer to the write buffer,
 717  *      watching for wraparound. Then we wake up the reader.
 718  */
 719    
 720         unix_lock(pupd);
 721 
 722         do 
 723         {
 724                 int part, cando;
 725 
 726                 if (space <= 0) 
 727                 {
 728                         printk("UNIX: write: SPACE IS NEGATIVE!!!\n");
 729                         send_sig(SIGKILL, current, 1);
 730                         return(-EPIPE);
 731                 }
 732 
 733                 /*
 734                  *      We may become disconnected inside this loop, so watch
 735                  *      for it (peerupd is safe until we close).
 736                  */
 737                  
 738                 if (sock->state == SS_DISCONNECTING) 
 739                 {
 740                         send_sig(SIGPIPE, current, 1);
 741                         unix_unlock(pupd);
 742                         return(-EPIPE);
 743                 }
 744                 
 745                 if ((cando = todo) > space) 
 746                         cando = space;
 747 
 748                 if (cando >(part = BUF_SIZE - pupd->bp_head))
 749                         cando = part;
 750         
 751                 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
 752                 pupd->bp_head =(pupd->bp_head + cando) &(BUF_SIZE-1);
 753                 ubuf += cando;
 754                 todo -= cando;
 755                 if (sock->state == SS_CONNECTED)
 756                 {
 757                         wake_up_interruptible(sock->conn->wait);
 758                         sock_wake_async(sock->conn, 1);
 759                 }
 760                 space = UN_BUF_SPACE(pupd);
 761         }
 762         while(todo && space);
 763 
 764         unix_unlock(pupd);
 765         return(size - todo);
 766 }
 767 
 768 /*
 769  *      Select on a unix domain socket.
 770  */
 771 
 772 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 773 {
 774         struct unix_proto_data *upd, *peerupd;
 775 
 776         /* 
 777          *      Handle server sockets specially.
 778          */
 779         if (sock->flags & SO_ACCEPTCON) 
 780         {
 781                 if (sel_type == SEL_IN) 
 782                 {
 783                         if (sock->iconn) 
 784                                 return(1);
 785                         select_wait(sock->wait, wait);
 786                         return(sock->iconn ? 1 : 0);
 787                 }
 788                 select_wait(sock->wait, wait);
 789                 return(0);
 790         }
 791 
 792         if (sel_type == SEL_IN) 
 793         {
 794                 upd = UN_DATA(sock);
 795                 if (UN_BUF_AVAIL(upd))  /* even if disconnected */
 796                         return(1);
 797                 else if (sock->state != SS_CONNECTED) 
 798                 {
 799                         return(1);
 800                 }
 801                 select_wait(sock->wait,wait);
 802                 return(0);
 803         }
 804 
 805         if (sel_type == SEL_OUT) 
 806         {
 807                 if (sock->state != SS_CONNECTED) 
 808                 {
 809                         return(1);
 810                 }
 811                 peerupd = UN_DATA(sock->conn);
 812                 if (UN_BUF_SPACE(peerupd) > 0) 
 813                         return(1);
 814                 select_wait(sock->wait,wait);
 815                 return(0);
 816         }
 817 
 818         /*
 819          * Exceptions - SEL_EX 
 820          */
 821 
 822         return(0);
 823 }
 824 
 825 
 826 /*
 827  *      ioctl() calls sent to an AF_UNIX socket
 828  */
 829 
 830 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 831 {
 832         struct unix_proto_data *upd, *peerupd;
 833         int er;
 834 
 835         upd = UN_DATA(sock);
 836         peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
 837 
 838         switch(cmd) 
 839         {
 840                 case TIOCINQ:
 841                         if (sock->flags & SO_ACCEPTCON) 
 842                                 return(-EINVAL);
 843                         er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
 844                         if(er)
 845                                 return er;
 846                         if (UN_BUF_AVAIL(upd) || peerupd)
 847                                 put_fs_long(UN_BUF_AVAIL(upd),(unsigned long *)arg);
 848                         else
 849                                 put_fs_long(0,(unsigned long *)arg);
 850                         break;
 851                 case TIOCOUTQ:
 852                         if (sock->flags & SO_ACCEPTCON) 
 853                                 return(-EINVAL);
 854                         er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
 855                         if(er)
 856                                 return er;
 857                         if (peerupd) 
 858                                 put_fs_long(UN_BUF_SPACE(peerupd),(unsigned long *)arg);
 859                         else
 860                                 put_fs_long(0,(unsigned long *)arg);
 861                         break;
 862                 default:
 863                         return(-EINVAL);
 864         }
 865         return(0);
 866 }
 867 
 868 
 869 static struct proto_ops unix_proto_ops = {
 870         AF_UNIX,
 871         unix_proto_create,
 872         unix_proto_dup,
 873         unix_proto_release,
 874         unix_proto_bind,
 875         unix_proto_connect,
 876         unix_proto_socketpair,
 877         unix_proto_accept,
 878         unix_proto_getname,
 879         unix_proto_read,
 880         unix_proto_write,
 881         unix_proto_select,
 882         unix_proto_ioctl,
 883         unix_proto_listen,
 884         unix_proto_send,
 885         unix_proto_recv,
 886         unix_proto_sendto,
 887         unix_proto_recvfrom,
 888         unix_proto_shutdown,
 889         unix_proto_setsockopt,
 890         unix_proto_getsockopt,
 891         NULL                            /* unix_proto_fcntl     */
 892 };
 893 
 894 /*
 895  *      Initialise the Unix domain protocol.
 896  */
 897 
 898 void unix_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
 899 {
 900         struct unix_proto_data *upd;
 901 
 902         /*
 903          *      Tell SOCKET that we are alive... 
 904          */
 905 
 906         (void) sock_register(unix_proto_ops.family, &unix_proto_ops);
 907 
 908         for(upd = unix_datas; upd <= last_unix_data; ++upd) 
 909         {
 910                 upd->refcnt = 0;
 911         }
 912 }

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