root/net/unix.c

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

DEFINITIONS

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

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