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 
 337         PRINTK(("unix_proto_bind: socket 0x%x, len=%d\n", sock,
 338                sockaddr_len));
 339         if (sockaddr_len <= UN_PATH_OFFSET ||
 340             sockaddr_len > sizeof(struct sockaddr_un)) {
 341                 PRINTK(("unix_proto_bind: bad length %d\n", sockaddr_len));
 342                 return -EINVAL;
 343         }
 344         if (upd->sockaddr_len || upd->inode) {
 345                 printk("unix_proto_bind: already bound!\n");
 346                 return -EINVAL;
 347         }
 348         verify_area(VERIFY_WRITE,umyaddr, sockaddr_len);
 349         memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
 350         if (upd->sockaddr_un.sun_family != AF_UNIX) {
 351                 PRINTK(("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
 352                        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         i = do_mknod(fname, S_IFSOCK | 0777, 0);
 359         if (i == 0)
 360                 i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
 361         if (i < 0) {
 362                 printk("unix_proto_bind: can't open socket %s\n", fname);
 363                 return i;
 364         }
 365 
 366         upd->sockaddr_len = sockaddr_len;       /* now its legal */
 367         PRINTK(("unix_proto_bind: bound socket address: "));
 368 #ifdef SOCK_DEBUG
 369         sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
 370 #endif
 371         PRINTK(("to inode 0x%x\n", upd->inode));
 372         return 0;
 373 }
 374 
 375 /*
 376  * perform a connection. we can only connect to unix sockets (i can't for
 377  * the life of me find an application where that wouldn't be the case!)
 378  */
 379 static int
 380 unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 381                    int sockaddr_len, int flags)
 382 {
 383         int i;
 384         struct unix_proto_data *serv_upd;
 385         struct sockaddr_un sockun;
 386         char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
 387         struct inode *inode;
 388 
 389         PRINTK(("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
 390                sockaddr_len));
 391 
 392         if (sockaddr_len <= UN_PATH_OFFSET ||
 393             sockaddr_len > sizeof(struct sockaddr_un)) {
 394                 PRINTK(("unix_proto_connect: bad length %d\n", sockaddr_len));
 395                 return -EINVAL;
 396         }
 397 
 398         if (sock->state == SS_CONNECTING)
 399           return (-EINPROGRESS);
 400 
 401         if (sock->state == SS_CONNECTED)
 402           return (-EISCONN);
 403 
 404         verify_area(VERIFY_WRITE,uservaddr, sockaddr_len);
 405         memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
 406         if (sockun.sun_family != AF_UNIX) {
 407                 PRINTK(("unix_proto_connect: family is %d, not AF_UNIX (%d)\n",
 408                        sockun.sun_family, AF_UNIX));
 409                 return -EINVAL;
 410         }
 411 
 412         /*
 413          * try to open the name in the filesystem - this is how we
 414          * identify ourselves and our server. Note that we don't
 415          * hold onto the inode that long, just enough to find our
 416          * server. When we're connected, we mooch off the server.
 417          */
 418         memcpy(fname, sockun.sun_path, sockaddr_len-UN_PATH_OFFSET);
 419         fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
 420         i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
 421         if (i < 0) {
 422                 PRINTK(("unix_proto_connect: can't open socket %s\n", fname));
 423                 return i;
 424         }
 425         serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
 426         iput(inode);
 427         if (!serv_upd) {
 428                 PRINTK(("unix_proto_connect: can't locate peer %s at inode 0x%x\n",
 429                         fname, inode));
 430                 return -EINVAL;
 431         }
 432         if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
 433                 PRINTK(("unix_proto_connect: can't await connection\n"));
 434                 return i;
 435         }
 436         unix_data_ref(UN_DATA(sock->conn));
 437         UN_DATA(sock)->peerupd = UN_DATA(sock->conn); /* ref server */
 438         return 0;
 439 }
 440 
 441 /*
 442  * to do a socketpair, we just connect the two datas, easy! since we
 443  * always wait on the socket inode, they're no contention for a wait area,
 444  * and deadlock prevention in the case of a process writing to itself is,
 445  * ignored, in true unix fashion!
 446  */
 447 static int
 448 unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
 449 {
 450         struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
 451 
 452         unix_data_ref(upd1);
 453         unix_data_ref(upd2);
 454         upd1->peerupd = upd2;
 455         upd2->peerupd = upd1;
 456         return 0;
 457 }
 458 
 459 /*
 460  * on accept, we ref the peer's data for safe writes
 461  */
 462 static int
 463 unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 464 {
 465    struct socket *clientsock;
 466 
 467         PRINTK(("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n",
 468                sock, newsock));
 469 
 470         /*
 471          * if there aren't any sockets awaiting connection, then wait for
 472          * one, unless nonblocking
 473          */
 474         while (!(clientsock = sock->iconn)) {
 475                 if (flags & O_NONBLOCK)
 476                         return -EAGAIN;
 477                 interruptible_sleep_on(sock->wait);
 478                 if (current->signal & ~current->blocked) {
 479                         PRINTK(("sys_accept: sleep was interrupted\n"));
 480                         return -ERESTARTSYS;
 481                 }
 482         }
 483 
 484         /*
 485          * great. finish the connection relative to server and client,
 486          * wake up the client and return the new fd to the server
 487          */
 488         sock->iconn = clientsock->next;
 489         clientsock->next = NULL;
 490         newsock->conn = clientsock;
 491         clientsock->conn = newsock;
 492         clientsock->state = SS_CONNECTED;
 493         newsock->state = SS_CONNECTED;
 494         wake_up(clientsock->wait);
 495         unix_data_ref (UN_DATA(newsock->conn));
 496         UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn);
 497         UN_DATA(newsock)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
 498         UN_DATA(newsock)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
 499         UN_DATA(newsock->conn)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
 500         UN_DATA(newsock->conn)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
 501         return 0;
 502 }
 503 
 504 /*
 505  * gets the current name or the name of the connected socket.
 506  */
 507 static int
 508 unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 509                    int *usockaddr_len, int peer)
 510 {
 511         struct unix_proto_data *upd;
 512         int len;
 513 
 514         PRINTK(("unix_proto_getname: socket 0x%x for %s\n", sock,
 515                peer ? "peer" : "self"));
 516         if (peer) {
 517                 if (sock->state != SS_CONNECTED) {
 518                         PRINTK(("unix_proto_getname: socket not connected\n"));
 519                         return -EINVAL;
 520                 }
 521                 upd = UN_DATA(sock->conn);
 522         }
 523         else
 524                 upd = UN_DATA(sock);
 525         verify_area(VERIFY_WRITE,usockaddr_len, sizeof(*usockaddr_len));
 526         if ((len = get_fs_long(usockaddr_len)) <= 0)
 527                 return -EINVAL;
 528         if (len > upd->sockaddr_len)
 529                 len = upd->sockaddr_len;
 530         if (len) {
 531                 verify_area(VERIFY_WRITE,usockaddr, len);
 532                 memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
 533         }
 534         put_fs_long(len, usockaddr_len);
 535         return 0;
 536 }
 537 
 538 /*
 539  * we read from our own buf.
 540  */
 541 static int
 542 unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 543 {
 544         struct unix_proto_data *upd;
 545         int todo, avail;
 546 
 547         if ((todo = size) <= 0)
 548                 return 0;
 549         upd = UN_DATA(sock);
 550         while (!(avail = UN_BUF_AVAIL(upd))) {
 551                 if (sock->state != SS_CONNECTED) {
 552                         PRINTK(("unix_proto_read: socket not connected\n"));
 553                         return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL;
 554                 }
 555                 PRINTK(("unix_proto_read: no data available...\n"));
 556                 if (nonblock)
 557                         return -EAGAIN;
 558                 interruptible_sleep_on(sock->wait);
 559                 if (current->signal & ~current->blocked) {
 560                         PRINTK(("unix_proto_read: interrupted\n"));
 561                         return -ERESTARTSYS;
 562                 }
 563                 if (sock->state == SS_DISCONNECTING) {
 564                         PRINTK(("unix_proto_read: disconnected\n"));
 565                         return 0;
 566                 }
 567         }
 568 
 569         /*
 570          * copy from the read buffer into the user's buffer, watching for
 571          * wraparound. then we wake up the writer
 572          */
 573         do {
 574                 int part, cando;
 575 
 576                 if (avail <= 0) {
 577                         PRINTK(("unix_proto_read: AVAIL IS NEGATIVE!!!\n"));
 578                         send_sig(SIGKILL,current,1);
 579                         return -EINTR;
 580                 }
 581 
 582                 if ((cando = todo) > avail)
 583                         cando = avail;
 584                 if (cando > (part = BUF_SIZE - upd->bp_tail))
 585                         cando = part;
 586                 PRINTK(("unix_proto_read: avail=%d, todo=%d, cando=%d\n",
 587                        avail, todo, cando));
 588                 verify_area(VERIFY_WRITE,ubuf, cando);
 589                 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
 590                 upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1);
 591                 ubuf += cando;
 592                 todo -= cando;
 593                 if (sock->state == SS_CONNECTED)
 594                         wake_up(sock->conn->wait);
 595                 avail = UN_BUF_AVAIL(upd);
 596         } while (todo && avail);
 597         return size - todo;
 598 }
 599 
 600 /*
 601  * we write to our peer's buf. when we connected we ref'd this peer so we
 602  * are safe that the buffer remains, even after the peer has disconnected,
 603  * which we check other ways.
 604  */
 605 static int
 606 unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 607 {
 608         struct unix_proto_data *pupd;
 609         int todo, space;
 610 
 611         if ((todo = size) <= 0)
 612                 return 0;
 613         if (sock->state != SS_CONNECTED) {
 614                 PRINTK(("unix_proto_write: socket not connected\n"));
 615                 if (sock->state == SS_DISCONNECTING) {
 616                         send_sig(SIGPIPE,current,1);
 617                         return -EINTR;
 618                 }
 619                 return -EINVAL;
 620         }
 621         pupd = UN_DATA(sock)->peerupd;  /* safer than sock->conn */
 622 
 623         while (!(space = UN_BUF_SPACE(pupd))) {
 624                 PRINTK(("unix_proto_write: no space left...\n"));
 625                 if (nonblock)
 626                         return -EAGAIN;
 627                 interruptible_sleep_on(sock->wait);
 628                 if (current->signal & ~current->blocked) {
 629                         PRINTK(("unix_proto_write: interrupted\n"));
 630                         return -ERESTARTSYS;
 631                 }
 632                 if (sock->state == SS_DISCONNECTING) {
 633                         PRINTK(("unix_proto_write: disconnected (SIGPIPE)\n"));
 634                         send_sig(SIGPIPE,current,1);
 635                         return -EINTR;
 636                 }
 637         }
 638 
 639         /*
 640          * copy from the user's buffer to the write buffer, watching for
 641          * wraparound. then we wake up the reader
 642          */
 643         do {
 644                 int part, cando;
 645 
 646                 if (space <= 0) {
 647                         PRINTK(("unix_proto_write: SPACE IS NEGATIVE!!!\n"));
 648                         send_sig(SIGKILL,current,1);
 649                         return -EINTR;
 650                 }
 651 
 652                 /*
 653                  * we may become disconnected inside this loop, so watch
 654                  * for it (peerupd is safe until we close)
 655                  */
 656                 if (sock->state == SS_DISCONNECTING) {
 657                         send_sig(SIGPIPE,current,1);
 658                         return -EINTR;
 659                 }
 660                 if ((cando = todo) > space)
 661                         cando = space;
 662                 if (cando > (part = BUF_SIZE - pupd->bp_head))
 663                         cando = part;
 664                 PRINTK(("unix_proto_write: space=%d, todo=%d, cando=%d\n",
 665                        space, todo, cando));
 666                 verify_area(VERIFY_WRITE,ubuf, cando);
 667                 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
 668                 pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1);
 669                 ubuf += cando;
 670                 todo -= cando;
 671                 if (sock->state == SS_CONNECTED)
 672                         wake_up(sock->conn->wait);
 673                 space = UN_BUF_SPACE(pupd);
 674         } while (todo && space);
 675         return size - todo;
 676 }
 677 
 678 static int
 679 unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 680 {
 681         struct unix_proto_data *upd, *peerupd;
 682 
 683         /*
 684          * handle server sockets specially
 685          */
 686         if (sock->flags & SO_ACCEPTCON) {
 687                 if (sel_type == SEL_IN) {
 688                         PRINTK(("sock_select: %sconnections pending\n",
 689                                sock->iconn ? "" : "no "));
 690                         if (sock->iconn)
 691                                 return 1;
 692                         select_wait(sock->wait, wait);
 693                         return sock->iconn ? 1 : 0;
 694                 }
 695                 PRINTK(("sock_select: nothing else for server socket\n"));
 696                 select_wait(sock->wait, wait);
 697                 return 0;
 698         }
 699 
 700         if (sel_type == SEL_IN) {
 701                 upd = UN_DATA(sock);
 702                 PRINTK(("unix_proto_select: there is%s data available\n",
 703                        UN_BUF_AVAIL(upd) ? "" : " no"));
 704                 if (UN_BUF_AVAIL(upd))  /* even if disconnected */
 705                         return 1;
 706                 else if (sock->state != SS_CONNECTED) {
 707                         PRINTK(("unix_proto_select: socket not connected (read EOF)\n"));
 708                         return 1;
 709                 }
 710                 select_wait(sock->wait,wait);
 711                 return 0;
 712         }
 713         if (sel_type == SEL_OUT) {
 714                 if (sock->state != SS_CONNECTED) {
 715                         PRINTK(("unix_proto_select: socket not connected (write EOF)\n"));
 716                         return 1;
 717                 }
 718                 peerupd = UN_DATA(sock->conn);
 719                 PRINTK(("unix_proto_select: there is%s space available\n",
 720                        UN_BUF_SPACE(peerupd) ? "" : " no"));
 721                 if (UN_BUF_SPACE(peerupd) > 0)
 722                         return 1;
 723                 select_wait(sock->wait,wait);
 724                 return 0;
 725         }
 726         /* SEL_EX */
 727         PRINTK(("unix_proto_select: there are no exceptions here?!\n"));
 728         return 0;
 729 }
 730 
 731 static int
 732 unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 733 {
 734         struct unix_proto_data *upd, *peerupd;
 735 
 736         upd = UN_DATA(sock);
 737         peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
 738 
 739         switch (cmd) {
 740 
 741         case TIOCINQ:
 742                 if (sock->flags & SO_ACCEPTCON)
 743                         return -EINVAL;
 744                 verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
 745                 if (UN_BUF_AVAIL(upd) || peerupd)
 746                         put_fs_long(UN_BUF_AVAIL(upd), (unsigned long *)arg);
 747                 else
 748                         put_fs_long(1, (unsigned long *)arg); /* read EOF */
 749                 break;
 750 
 751         case TIOCOUTQ:
 752                 if (sock->flags & SO_ACCEPTCON)
 753                         return -EINVAL;
 754                 verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
 755                 if (peerupd)
 756                         put_fs_long(UN_BUF_SPACE(peerupd),
 757                                     (unsigned long *)arg);
 758                 else
 759                         put_fs_long(0, (unsigned long *)arg);
 760                 break;
 761 
 762         default:
 763                 return -EINVAL;
 764         }
 765         return 0;
 766 }
 767 
 768 static int
 769 unix_proto_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 770 {
 771         struct unix_proto_data *upd;
 772 
 773         PRINTK(("unix_proto_init: initializing...\n"));
 774         for (upd = unix_datas; upd <= last_unix_data; ++upd)
 775                 upd->refcnt = 0;
 776         return 0;
 777 }

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