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/config.h>
  31 #include <linux/kernel.h>
  32 #include <linux/major.h>
  33 #include <linux/signal.h>
  34 #include <linux/sched.h>
  35 #include <linux/errno.h>
  36 #include <linux/string.h>
  37 #include <linux/stat.h>
  38 #include <linux/socket.h>
  39 #include <linux/un.h>
  40 #include <linux/fcntl.h>
  41 #include <linux/termios.h>
  42 #include <linux/sockios.h>
  43 #include <linux/net.h>
  44 #include <linux/fs.h>
  45 #include <linux/malloc.h>
  46 
  47 #include <asm/system.h>
  48 #include <asm/segment.h>
  49 
  50 #include <stdarg.h>
  51 
  52 #include "unix.h"
  53 
  54 struct unix_proto_data unix_datas[NSOCKETS];
  55 
  56 static int unix_proto_create(struct socket *sock, int protocol);
  57 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock);
  58 static int unix_proto_release(struct socket *sock, struct socket *peer);
  59 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
  60                            int sockaddr_len);
  61 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
  62                               int sockaddr_len, int flags);
  63 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2);
  64 static int unix_proto_accept(struct socket *sock, struct socket *newsock, 
  65                              int flags);
  66 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
  67                               int *usockaddr_len, int peer);
  68 static int unix_proto_read(struct socket *sock, char *ubuf, int size,
  69                            int nonblock);
  70 static int unix_proto_write(struct socket *sock, char *ubuf, int size,
  71                             int nonblock);
  72 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait);
  73 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd,
  74                             unsigned long arg);
  75 static int unix_proto_listen(struct socket *sock, int backlog);
  76 static int unix_proto_send(struct socket *sock, void *buff, int len,
  77                             int nonblock, unsigned flags);
  78 static int unix_proto_recv(struct socket *sock, void *buff, int len,
  79                             int nonblock, unsigned flags);
  80 static int unix_proto_sendto(struct socket *sock, void *buff, int len,
  81                               int nonblock, unsigned flags,
  82                               struct sockaddr *addr, int addr_len);
  83 static int unix_proto_recvfrom(struct socket *sock, void *buff, int len,
  84                                 int nonblock, unsigned flags,
  85                                 struct sockaddr *addr, int *addr_len);
  86 
  87 static int unix_proto_shutdown(struct socket *sock, int how);
  88 
  89 static int unix_proto_setsockopt(struct socket *sock, int level, int optname,
  90                                   char *optval, int optlen);
  91 static int unix_proto_getsockopt(struct socket *sock, int level, int optname,
  92                                   char *optval, int *optlen);
  93 
  94 
  95 static inline int
  96 min(int a, int b)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98   if (a < b) return(a);
  99   return(b);
 100 }
 101 
 102 
 103 
 104 /* Support routines doing anti page fault locking 
 105  * FvK & Matt Dillon (borrowed From NET2E3)
 106  */
 107 
 108 /*
 109  * Locking for unix-domain sockets.  We don't use the socket structure's
 110  * wait queue because it is allowed to 'go away' outside of our control,
 111  * whereas unix_proto_data structures stick around.
 112  */
 113 static void unix_lock(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 114 {
 115         while (upd->lock_flag)
 116                 sleep_on(&upd->wait);
 117         upd->lock_flag = 1;
 118 }
 119 
 120 
 121 static void unix_unlock(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         upd->lock_flag = 0;
 124         wake_up(&upd->wait);
 125 }
 126 
 127 /* don't have to do anything. */
 128 static int
 129 unix_proto_listen(struct socket *sock, int backlog)
     /* [previous][next][first][last][top][bottom][index][help] */
 130 {
 131   return(0);
 132 }
 133 
 134 
 135 static int
 136 unix_proto_setsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 137                       char *optval, int optlen)
 138 {
 139   return(-EOPNOTSUPP);
 140 }
 141 
 142 
 143 static int
 144 unix_proto_getsockopt(struct socket *sock, int level, int optname,
     /* [previous][next][first][last][top][bottom][index][help] */
 145                       char *optval, int *optlen)
 146 {
 147   return(-EOPNOTSUPP);
 148 }
 149 
 150 static int
 151 unix_proto_sendto(struct socket *sock, void *buff, int len, int nonblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
 152                   unsigned flags,  struct sockaddr *addr, int addr_len)
 153 {
 154   return(-EOPNOTSUPP);
 155 }     
 156 
 157 static int
 158 unix_proto_recvfrom(struct socket *sock, void *buff, int len, int nonblock, 
     /* [previous][next][first][last][top][bottom][index][help] */
 159                     unsigned flags, struct sockaddr *addr, int *addr_len)
 160 {
 161   return(-EOPNOTSUPP);
 162 }     
 163 
 164 
 165 static int
 166 unix_proto_shutdown(struct socket *sock, int how)
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168   return(-EOPNOTSUPP);
 169 }
 170 
 171 
 172 /* This error needs to be checked. */
 173 static int
 174 unix_proto_send(struct socket *sock, void *buff, int len, int nonblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 175                 unsigned flags)
 176 {
 177   if (flags != 0) return(-EINVAL);
 178   return(unix_proto_write(sock, (char *) buff, len, nonblock));
 179 }
 180 
 181 
 182 /* This error needs to be checked. */
 183 static int
 184 unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 185                 unsigned flags)
 186 {
 187   if (flags != 0) return(-EINVAL);
 188   return(unix_proto_read(sock, (char *) buff, len, nonblock));
 189 }
 190 
 191 
 192 static struct unix_proto_data *
 193 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len,
     /* [previous][next][first][last][top][bottom][index][help] */
 194                  struct inode *inode)
 195 {
 196   struct unix_proto_data *upd;
 197 
 198   for(upd = unix_datas; upd <= last_unix_data; ++upd) {
 199         if (upd->refcnt > 0 && upd->socket &&
 200             upd->socket->state == SS_UNCONNECTED &&
 201             upd->sockaddr_un.sun_family == sockun->sun_family &&
 202             upd->inode == inode) return(upd);
 203   }
 204   return(NULL);
 205 }
 206 
 207 
 208 static struct unix_proto_data *
 209 unix_data_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 210 {
 211   struct unix_proto_data *upd;
 212 
 213   cli();
 214   for(upd = unix_datas; upd <= last_unix_data; ++upd) {
 215         if (!upd->refcnt) {
 216                 upd->refcnt = -1;       /* unix domain socket not yet initialised - bgm */
 217                 sti();
 218                 upd->socket = NULL;
 219                 upd->sockaddr_len = 0;
 220                 upd->sockaddr_un.sun_family = 0;
 221                 upd->buf = NULL;
 222                 upd->bp_head = upd->bp_tail = 0;
 223                 upd->inode = NULL;
 224                 upd->peerupd = NULL;
 225                 return(upd);
 226         }
 227   }
 228   sti();
 229   return(NULL);
 230 }
 231 
 232 
 233 static inline void
 234 unix_data_ref(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 235 {
 236   if (!upd) {
 237     return;
 238   }
 239   ++upd->refcnt;
 240 }
 241 
 242 
 243 static void
 244 unix_data_deref(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 245 {
 246   if (!upd) {
 247     return;
 248   }
 249   if (upd->refcnt == 1) {
 250         if (upd->buf) {
 251                 free_page((unsigned long)upd->buf);
 252                 upd->buf = NULL;
 253                 upd->bp_head = upd->bp_tail = 0;
 254         }
 255   }
 256   --upd->refcnt;
 257 }
 258 
 259 
 260 /*
 261  * Upon a create, we allocate an empty protocol data,
 262  * and grab a page to buffer writes.
 263  */
 264 static int
 265 unix_proto_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267   struct unix_proto_data *upd;
 268 
 269   if (protocol != 0) {
 270         return(-EINVAL);
 271   }
 272   if (!(upd = unix_data_alloc())) {
 273         printk("UNIX: create: can't allocate buffer\n");
 274         return(-ENOMEM);
 275   }
 276   if (!(upd->buf = (char*) get_free_page(GFP_USER))) {
 277         printk("UNIX: create: can't get page!\n");
 278         unix_data_deref(upd);
 279         return(-ENOMEM);
 280   }
 281   upd->protocol = protocol;
 282   upd->socket = sock;
 283   UN_DATA(sock) = upd;
 284   upd->refcnt = 1;      /* Now its complete - bgm */
 285   return(0);
 286 }
 287 
 288 
 289 static int
 290 unix_proto_dup(struct socket *newsock, struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 291 {
 292   struct unix_proto_data *upd = UN_DATA(oldsock);
 293 
 294   return(unix_proto_create(newsock, upd->protocol));
 295 }
 296 
 297 
 298 static int
 299 unix_proto_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 {
 301   struct unix_proto_data *upd = UN_DATA(sock);
 302 
 303   if (!upd) return(0);
 304   if (upd->socket != sock) {
 305         printk("UNIX: release: socket link mismatch!\n");
 306         return(-EINVAL);
 307   }
 308   if (upd->inode) {
 309         iput(upd->inode);
 310         upd->inode = NULL;
 311   }
 312   UN_DATA(sock) = NULL;
 313   upd->socket = NULL;
 314   if (upd->peerupd) unix_data_deref(upd->peerupd);
 315   unix_data_deref(upd);
 316   return(0);
 317 }
 318 
 319 
 320 /*
 321  * Bind a name to a socket.
 322  * This is where much of the work is done: we allocate a fresh page for
 323  * the buffer, grab the appropriate inode and set things up.
 324  *
 325  * FIXME: what should we do if an address is already bound?
 326  *        Here we return EINVAL, but it may be necessary to re-bind.
 327  *        I think thats what BSD does in the case of datagram sockets...
 328  */
 329 static int
 330 unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 331                 int sockaddr_len)
 332 {
 333   char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
 334   struct unix_proto_data *upd = UN_DATA(sock);
 335   unsigned long old_fs;
 336   int i;
 337   int er;
 338 
 339   if (sockaddr_len <= UN_PATH_OFFSET ||
 340       sockaddr_len > sizeof(struct sockaddr_un)) {
 341         return(-EINVAL);
 342   }
 343   if (upd->sockaddr_len || upd->inode) {
 344         printk("UNIX: bind: already bound!\n");
 345         return(-EINVAL);
 346   }
 347   er=verify_area(VERIFY_WRITE, umyaddr, sockaddr_len);
 348   if(er)
 349         return er;
 350   memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
 351   upd->sockaddr_un.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
 352   if (upd->sockaddr_un.sun_family != AF_UNIX) {
 353         return(-EINVAL);
 354   }
 355 
 356   memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
 357   fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
 358   old_fs = get_fs();
 359   set_fs(get_ds());
 360   i = do_mknod(fname, S_IFSOCK | S_IRWXUGO, 0);
 361   if (i == 0) i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
 362   set_fs(old_fs);
 363   if (i < 0) {
 364         printk("UNIX: bind: can't open socket %s\n", fname);
 365         return(i);
 366   }
 367   upd->sockaddr_len = sockaddr_len;     /* now its legal */
 368 
 369   return(0);
 370 }
 371 
 372 
 373 /*
 374  * Perform a connection. we can only connect to unix sockets
 375  * (I can't for the life of me find an application where that
 376  * wouldn't be the case!)
 377  */
 378 static int
 379 unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 380                    int sockaddr_len, int flags)
 381 {
 382   char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
 383   struct sockaddr_un sockun;
 384   struct unix_proto_data *serv_upd;
 385   struct inode *inode;
 386   unsigned long old_fs;
 387   int i;
 388   int er;
 389 
 390   if (sockaddr_len <= UN_PATH_OFFSET ||
 391       sockaddr_len > sizeof(struct sockaddr_un)) {
 392         return(-EINVAL);
 393   }
 394   if (sock->state == SS_CONNECTING) return(-EINPROGRESS);
 395   if (sock->state == SS_CONNECTED) return(-EISCONN);
 396 
 397   er=verify_area(VERIFY_READ, uservaddr, sockaddr_len);
 398   if(er)
 399         return er;
 400   memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
 401   sockun.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
 402   if (sockun.sun_family != AF_UNIX) {
 403         return(-EINVAL);
 404   }
 405 
 406   /*
 407    * Try to open the name in the filesystem - this is how we
 408    * identify ourselves and our server. Note that we don't
 409    * hold onto the inode that long, just enough to find our
 410    * server. When we're connected, we mooch off the server.
 411    */
 412   memcpy(fname, sockun.sun_path, sockaddr_len-UN_PATH_OFFSET);
 413   fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
 414   old_fs = get_fs();
 415   set_fs(get_ds());
 416   i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
 417   set_fs(old_fs);
 418   if (i < 0) {
 419         return(i);
 420   }
 421           
 422   serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
 423   iput(inode);
 424   if (!serv_upd) {
 425         return(-EINVAL);
 426   }
 427   if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
 428         return(i);
 429   }
 430   if (sock->conn) {
 431         unix_data_ref(UN_DATA(sock->conn));
 432         UN_DATA(sock)->peerupd = UN_DATA(sock->conn); /* ref server */
 433   }
 434   return(0);
 435 }
 436 
 437 
 438 /*
 439  * To do a socketpair, we just connect the two datas, easy!
 440  * Since we always wait on the socket inode, they're no contention
 441  * for a wait area, and deadlock prevention in the case of a process
 442  * writing to itself is, ignored, in true unix fashion!
 443  */
 444 static int
 445 unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
 446 {
 447   struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
 448 
 449   unix_data_ref(upd1);
 450   unix_data_ref(upd2);
 451   upd1->peerupd = upd2;
 452   upd2->peerupd = upd1;
 453   return(0);
 454 }
 455 
 456 
 457 /* On accept, we ref the peer's data for safe writes. */
 458 static int
 459 unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 460 {
 461   struct socket *clientsock;
 462 
 463   /*
 464    * If there aren't any sockets awaiting connection,
 465    * then wait for one, unless nonblocking.
 466    */
 467   while(!(clientsock = sock->iconn)) {
 468         if (flags & O_NONBLOCK) return(-EAGAIN);
 469         interruptible_sleep_on(sock->wait);
 470         if (current->signal & ~current->blocked) {
 471                 return(-ERESTARTSYS);
 472         }
 473   }
 474 
 475   /*
 476    * Great. Finish the connection relative to server and client,
 477    * wake up the client and return the new fd to the server.
 478    */
 479   sock->iconn = clientsock->next;
 480   clientsock->next = NULL;
 481   newsock->conn = clientsock;
 482   clientsock->conn = newsock;
 483   clientsock->state = SS_CONNECTED;
 484   newsock->state = SS_CONNECTED;
 485   unix_data_ref(UN_DATA(clientsock));
 486   UN_DATA(newsock)->peerupd            = UN_DATA(clientsock);
 487   UN_DATA(newsock)->sockaddr_un        = UN_DATA(sock)->sockaddr_un;
 488   UN_DATA(newsock)->sockaddr_len       = UN_DATA(sock)->sockaddr_len;
 489   wake_up_interruptible(clientsock->wait);
 490   return(0);
 491 }
 492 
 493 
 494 /* Gets the current name or the name of the connected socket. */
 495 static int
 496 unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 497                    int *usockaddr_len, int peer)
 498 {
 499   struct unix_proto_data *upd;
 500   int len;
 501   int er;
 502 
 503   if (peer) {
 504         if (sock->state != SS_CONNECTED) {
 505                 return(-EINVAL);
 506         }
 507         upd = UN_DATA(sock->conn);
 508   } else
 509         upd = UN_DATA(sock);
 510 
 511   er=verify_area(VERIFY_WRITE, usockaddr_len, sizeof(*usockaddr_len));
 512   if(er)
 513         return er;
 514   if ((len = get_fs_long(usockaddr_len)) <= 0) return(-EINVAL);
 515   if (len > upd->sockaddr_len) len = upd->sockaddr_len;
 516   if (len) {
 517         er=verify_area(VERIFY_WRITE, usockaddr, len);
 518         if(er)
 519                 return er;
 520         memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
 521   }
 522   put_fs_long(len, usockaddr_len);
 523   return(0);
 524 }
 525 
 526 
 527 /* We read from our own buf. */
 528 static int
 529 unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531   struct unix_proto_data *upd;
 532   int todo, avail;
 533   int er;
 534 
 535   if ((todo = size) <= 0) return(0);
 536   upd = UN_DATA(sock);
 537   while(!(avail = UN_BUF_AVAIL(upd))) {
 538         if (sock->state != SS_CONNECTED) {
 539                 return((sock->state == SS_DISCONNECTING) ? 0 : -EINVAL);
 540         }
 541         if (nonblock) return(-EAGAIN);
 542         interruptible_sleep_on(sock->wait);
 543         if (current->signal & ~current->blocked) {
 544                 return(-ERESTARTSYS);
 545         }
 546   }
 547 
 548   /*
 549    * Copy from the read buffer into the user's buffer,
 550    * watching for wraparound. Then we wake up the writer.
 551    */
 552    
 553   unix_lock(upd);
 554   do {
 555         int part, cando;
 556 
 557         if (avail <= 0) {
 558                 printk("UNIX: read: AVAIL IS NEGATIVE!!!\n");
 559                 send_sig(SIGKILL, current, 1);
 560                 return(-EPIPE);
 561         }
 562 
 563         if ((cando = todo) > avail) cando = avail;
 564         if (cando >(part = BUF_SIZE - upd->bp_tail)) cando = part;
 565         if((er=verify_area(VERIFY_WRITE,ubuf,cando))<0)
 566         {
 567                 unix_unlock(upd);
 568                 return er;
 569         }
 570         memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
 571         upd->bp_tail =(upd->bp_tail + cando) &(BUF_SIZE-1);
 572         ubuf += cando;
 573         todo -= cando;
 574         if (sock->state == SS_CONNECTED)
 575                 wake_up_interruptible(sock->conn->wait);
 576         avail = UN_BUF_AVAIL(upd);
 577   } while(todo && avail);
 578   unix_unlock(upd);
 579   return(size - todo);
 580 }
 581 
 582 
 583 /*
 584  * We write to our peer's buf. When we connected we ref'd this
 585  * peer so we are safe that the buffer remains, even after the
 586  * peer has disconnected, which we check other ways.
 587  */
 588 static int
 589 unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 590 {
 591   struct unix_proto_data *pupd;
 592   int todo, space;
 593   int er;
 594 
 595   if ((todo = size) <= 0) return(0);
 596   if (sock->state != SS_CONNECTED) {
 597         if (sock->state == SS_DISCONNECTING) {
 598                 send_sig(SIGPIPE, current, 1);
 599                 return(-EPIPE);
 600         }
 601         return(-EINVAL);
 602   }
 603   pupd = UN_DATA(sock)->peerupd;        /* safer than sock->conn */
 604 
 605   while(!(space = UN_BUF_SPACE(pupd))) {
 606         if (nonblock) return(-EAGAIN);
 607         interruptible_sleep_on(sock->wait);
 608         if (current->signal & ~current->blocked) {
 609                 return(-ERESTARTSYS);
 610         }
 611         if (sock->state == SS_DISCONNECTING) {
 612                 send_sig(SIGPIPE, current, 1);
 613                 return(-EPIPE);
 614         }
 615   }
 616 
 617   /*
 618    * Copy from the user's buffer to the write buffer,
 619    * watching for wraparound. Then we wake up the reader.
 620    */
 621    
 622   unix_lock(pupd);
 623   
 624   do {
 625         int part, cando;
 626 
 627         if (space <= 0) {
 628                 printk("UNIX: write: SPACE IS NEGATIVE!!!\n");
 629                 send_sig(SIGKILL, current, 1);
 630                 return(-EPIPE);
 631         }
 632 
 633         /*
 634          * We may become disconnected inside this loop, so watch
 635          * for it (peerupd is safe until we close).
 636          */
 637         if (sock->state == SS_DISCONNECTING) {
 638                 send_sig(SIGPIPE, current, 1);
 639                 unix_unlock(pupd);
 640                 return(-EPIPE);
 641         }
 642         if ((cando = todo) > space) cando = space;
 643         if (cando >(part = BUF_SIZE - pupd->bp_head)) cando = part;
 644         er=verify_area(VERIFY_READ, ubuf, cando);
 645         if(er)
 646         {
 647                 unix_unlock(pupd);
 648                 return er;
 649         }
 650         memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
 651         pupd->bp_head =(pupd->bp_head + cando) &(BUF_SIZE-1);
 652         ubuf += cando;
 653         todo -= cando;
 654         if (sock->state == SS_CONNECTED)
 655                 wake_up_interruptible(sock->conn->wait);
 656         space = UN_BUF_SPACE(pupd);
 657   } while(todo && space);
 658   unix_unlock(pupd);
 659   return(size - todo);
 660 }
 661 
 662 
 663 static int
 664 unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 665 {
 666   struct unix_proto_data *upd, *peerupd;
 667 
 668   /* Handle server sockets specially. */
 669   if (sock->flags & SO_ACCEPTCON) {
 670         if (sel_type == SEL_IN) {
 671                 if (sock->iconn) return(1);
 672                 select_wait(sock->wait, wait);
 673                 return(sock->iconn ? 1 : 0);
 674         }
 675         select_wait(sock->wait, wait);
 676         return(0);
 677   }
 678 
 679   if (sel_type == SEL_IN) {
 680         upd = UN_DATA(sock);
 681         if (UN_BUF_AVAIL(upd))  /* even if disconnected */
 682                         return(1);
 683         else if (sock->state != SS_CONNECTED) {
 684                 return(1);
 685         }
 686         select_wait(sock->wait,wait);
 687         return(0);
 688   }
 689   if (sel_type == SEL_OUT) {
 690         if (sock->state != SS_CONNECTED) {
 691                 return(1);
 692         }
 693         peerupd = UN_DATA(sock->conn);
 694         if (UN_BUF_SPACE(peerupd) > 0) return(1);
 695         select_wait(sock->wait,wait);
 696         return(0);
 697   }
 698 
 699   /* SEL_EX */
 700   return(0);
 701 }
 702 
 703 
 704 static int
 705 unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 706 {
 707   struct unix_proto_data *upd, *peerupd;
 708   int er;
 709 
 710   upd = UN_DATA(sock);
 711   peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
 712 
 713   switch(cmd) {
 714         case TIOCINQ:
 715                 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
 716                 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
 717                 if(er)
 718                         return er;
 719                 if (UN_BUF_AVAIL(upd) || peerupd)
 720                         put_fs_long(UN_BUF_AVAIL(upd),(unsigned long *)arg);
 721                   else
 722                         put_fs_long(0,(unsigned long *)arg);
 723                 break;
 724         case TIOCOUTQ:
 725                 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
 726                 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
 727                 if(er)
 728                         return er;
 729                 if (peerupd) put_fs_long(UN_BUF_SPACE(peerupd),
 730                                                 (unsigned long *)arg);
 731                   else
 732                         put_fs_long(0,(unsigned long *)arg);
 733                 break;
 734         default:
 735                 return(-EINVAL);
 736   }
 737   return(0);
 738 }
 739 
 740 
 741 static struct proto_ops unix_proto_ops = {
 742   AF_UNIX,
 743   unix_proto_create,
 744   unix_proto_dup,
 745   unix_proto_release,
 746   unix_proto_bind,
 747   unix_proto_connect,
 748   unix_proto_socketpair,
 749   unix_proto_accept,
 750   unix_proto_getname,
 751   unix_proto_read,
 752   unix_proto_write,
 753   unix_proto_select,
 754   unix_proto_ioctl,
 755   unix_proto_listen,
 756   unix_proto_send,
 757   unix_proto_recv,
 758   unix_proto_sendto,
 759   unix_proto_recvfrom,
 760   unix_proto_shutdown,
 761   unix_proto_setsockopt,
 762   unix_proto_getsockopt,
 763   NULL                          /* unix_proto_fcntl     */
 764 };
 765 
 766 
 767 void
 768 unix_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
 769 {
 770   struct unix_proto_data *upd;
 771 
 772   /* Tell SOCKET that we are alive... */
 773   (void) sock_register(unix_proto_ops.family, &unix_proto_ops);
 774 
 775   for(upd = unix_datas; upd <= last_unix_data; ++upd) {
 776         upd->refcnt = 0;
 777   }
 778 }

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