root/net/unix.c

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

DEFINITIONS

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

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

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