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. same_path
  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 
  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  * Since unix domain sockets use filenames to communicate, two sockets are
 189  * the same if their strings are the same, even if their lengths are different
 190  * (due to possible null terminations). Verified under SunOS 4.1.2
 191  */
 192 static int
 193 same_path(char *s1, int l1, char *s2, int l2)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195         /*
 196          * Skip chars while they're equal
 197          */
 198         for (; l1 && l2 && *s1 == *s2; ++s1, ++s2, --l1, --l2);
 199 
 200         /*
 201          * Both must be exhausted, or one must be null terminated and the
 202          * other either exhausted or null terminated, for the paths to be
 203          * equivalent
 204          */
 205         return ((l1 == 0 || *s1 == '\0') && (l2 == 0 || *s2 == '\0'));
 206 }
 207 
 208 static struct unix_proto_data *
 209 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 210 {
 211         struct unix_proto_data *upd;
 212 
 213         for (upd = unix_datas; upd <= last_unix_data; ++upd) {
 214                 if (upd->refcnt && upd->socket &&
 215                     upd->socket->state == SS_UNCONNECTED &&
 216                     upd->sockaddr_un.sun_family == sockun->sun_family &&
 217                     same_path(sockun->sun_path, sockaddr_len - UN_PATH_OFFSET,
 218                               upd->sockaddr_un.sun_path,
 219                               upd->sockaddr_len - UN_PATH_OFFSET))
 220                         return upd;
 221         }
 222         return NULL;
 223 }
 224 
 225 static struct unix_proto_data *
 226 unix_data_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 227 {
 228         struct unix_proto_data *upd;
 229 
 230         cli();
 231         for (upd = unix_datas; upd <= last_unix_data; ++upd) {
 232                 if (!upd->refcnt) {
 233                         upd->refcnt = 1;
 234                         sti();
 235                         upd->socket = NULL;
 236                         upd->sockaddr_len = 0;
 237                         upd->buf = NULL;
 238                         upd->bp_head = upd->bp_tail = 0;
 239                         upd->inode = NULL;
 240                         upd->peerupd = NULL;
 241                         return upd;
 242                 }
 243         }
 244         sti();
 245         return NULL;
 246 }
 247 
 248 static inline void
 249 unix_data_ref(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 250 {
 251         ++upd->refcnt;
 252         PRINTK("unix_data_ref: refing data 0x%x (%d)\n", upd, upd->refcnt);
 253 }
 254 
 255 static void
 256 unix_data_deref(struct unix_proto_data *upd)
     /* [previous][next][first][last][top][bottom][index][help] */
 257 {
 258         if (upd->refcnt == 1) {
 259                 PRINTK("unix_data_deref: releasing data 0x%x\n", upd);
 260                 if (upd->buf) {
 261                         free_page((unsigned long)upd->buf);
 262                         upd->buf = NULL;
 263                         upd->bp_head = upd->bp_tail = 0;
 264                 }
 265         }
 266         --upd->refcnt;
 267 }
 268 
 269 /*
 270  * upon a create, we allocate an empty protocol data, and grab a page to
 271  * buffer writes
 272  */
 273 static int
 274 unix_proto_create(struct socket *sock, int protocol)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276         struct unix_proto_data *upd;
 277 
 278         PRINTK("unix_proto_create: socket 0x%x, proto %d\n", sock, protocol);
 279         if (protocol != 0) {
 280                 PRINTK("unix_proto_create: protocol != 0\n");
 281                 return -EINVAL;
 282         }
 283         if (!(upd = unix_data_alloc())) {
 284                 printk("unix_proto_create: can't allocate buffer\n");
 285                 return -ENOMEM;
 286         }
 287         if (!(upd->buf = (char *)get_free_page(GFP_USER))) {
 288                 printk("unix_proto_create: can't get page!\n");
 289                 unix_data_deref(upd);
 290                 return -ENOMEM;
 291         }
 292         upd->protocol = protocol;
 293         upd->socket = sock;
 294         UN_DATA(sock) = upd;
 295         PRINTK("unix_proto_create: allocated data 0x%x\n", upd);
 296         return 0;
 297 }
 298 
 299 static int
 300 unix_proto_dup(struct socket *newsock, struct socket *oldsock)
     /* [previous][next][first][last][top][bottom][index][help] */
 301 {
 302         struct unix_proto_data *upd = UN_DATA(oldsock);
 303 
 304         return unix_proto_create(newsock, upd->protocol);
 305 }
 306 
 307 static int
 308 unix_proto_release(struct socket *sock, struct socket *peer)
     /* [previous][next][first][last][top][bottom][index][help] */
 309 {
 310         struct unix_proto_data *upd = UN_DATA(sock);
 311 
 312         PRINTK("unix_proto_release: socket 0x%x, unix_data 0x%x\n",
 313                sock, upd);
 314         if (!upd)
 315                 return 0;
 316         if (upd->socket != sock) {
 317                 printk("unix_proto_release: socket link mismatch!\n");
 318                 return -EINVAL;
 319         }
 320         if (upd->inode) {
 321                 PRINTK("unix_proto_release: releasing inode 0x%x\n",
 322                        upd->inode);
 323                 iput(upd->inode);
 324                 upd->inode = NULL;
 325         }
 326         UN_DATA(sock) = NULL;
 327         upd->socket = NULL;
 328         if (upd->peerupd)
 329                 unix_data_deref(upd->peerupd);
 330         unix_data_deref(upd);
 331         return 0;
 332 }
 333 
 334 /*
 335  * bind a name to a socket. this is where much of the work is done. we
 336  * allocate a fresh page for the buffer, grab the appropriate inode and
 337  * set things up.
 338  *
 339  * XXX what should we do if an address is already bound? here we return
 340  * EINVAL, but it may be necessary to re-bind. i think thats what bsd does
 341  * in the case of datagram sockets
 342  */
 343 static int
 344 unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 345                 int sockaddr_len)
 346 {
 347         struct unix_proto_data *upd = UN_DATA(sock);
 348         char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
 349         int i;
 350         unsigned long old_fs;
 351 
 352         PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock,
 353                sockaddr_len);
 354         if (sockaddr_len <= UN_PATH_OFFSET ||
 355             sockaddr_len > sizeof(struct sockaddr_un)) {
 356                 PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len);
 357                 return -EINVAL;
 358         }
 359         if (upd->sockaddr_len || upd->inode) {
 360                 printk("unix_proto_bind: already bound!\n");
 361                 return -EINVAL;
 362         }
 363         verify_area(umyaddr, sockaddr_len);
 364         memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
 365         if (upd->sockaddr_un.sun_family != AF_UNIX) {
 366                 PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
 367                        upd->sockaddr_un.sun_family, AF_UNIX);
 368                 return -EINVAL;
 369         }
 370 
 371         memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
 372         fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
 373         old_fs = get_fs();
 374         set_fs(get_ds());
 375         i = do_mknod(fname, S_IFSOCK | 0777, 0);
 376         if (i == 0)
 377                 i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
 378         set_fs(old_fs);
 379         if (i < 0) {
 380                 printk("unix_proto_bind: can't open socket %s\n", fname);
 381                 return i;
 382         }
 383 
 384         upd->sockaddr_len = sockaddr_len;       /* now its legal */
 385         PRINTK("unix_proto_bind: bound socket address: ");
 386 #ifdef SOCK_DEBUG
 387         sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
 388 #endif
 389         return 0;
 390 }
 391 
 392 /*
 393  * perform a connection. we can only connect to unix sockets (i can't for
 394  * the life of me find an application where that wouldn't be the case!)
 395  */
 396 static int
 397 unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 398                    int sockaddr_len, int flags)
 399 {
 400         int i;
 401         struct unix_proto_data *serv_upd;
 402         struct sockaddr_un sockun;
 403 
 404         PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
 405                sockaddr_len);
 406 
 407         if (sockaddr_len <= UN_PATH_OFFSET ||
 408             sockaddr_len > sizeof(struct sockaddr_un)) {
 409                 PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len);
 410                 return -EINVAL;
 411         }
 412 
 413         if (sock->state == SS_CONNECTING)
 414           return (-EINPROGRESS);
 415 
 416         if (sock->state == SS_CONNECTED)
 417           return (-EISCONN);
 418 
 419         verify_area(uservaddr, sockaddr_len);
 420         memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
 421         if (sockun.sun_family != AF_UNIX) {
 422                 PRINTK("unix_proto_connect: family is %d, not AF_UNIX (%d)\n",
 423                        sockun.sun_family, AF_UNIX);
 424                 return -EINVAL;
 425         }
 426         if (!(serv_upd = unix_data_lookup(&sockun, sockaddr_len))) {
 427                 PRINTK("unix_proto_connect: can't locate peer\n");
 428                 return -EINVAL;
 429         }
 430         if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
 431                 PRINTK("unix_proto_connect: can't await connection\n");
 432                 return i;
 433         }
 434         unix_data_ref(UN_DATA(sock->conn));
 435         UN_DATA(sock)->peerupd = UN_DATA(sock->conn); /* ref server */
 436         return 0;
 437 }
 438 
 439 /*
 440  * to do a socketpair, we make just connect the two datas, easy! since we
 441  * always wait on the socket inode, they're no contention for a wait area,
 442  * and deadlock prevention in the case of a process writing to itself is,
 443  * ignored, in true unix fashion!
 444  */
 445 static int
 446 unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
     /* [previous][next][first][last][top][bottom][index][help] */
 447 {
 448         struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
 449 
 450         unix_data_ref(upd1);
 451         unix_data_ref(upd2);
 452         upd1->peerupd = upd2;
 453         upd2->peerupd = upd1;
 454         return 0;
 455 }
 456 
 457 /*
 458  * on accept, we ref the peer's data for safe writes
 459  */
 460 static int
 461 unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 462 {
 463    struct socket *clientsock;
 464 
 465         PRINTK("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n",
 466                sock, newsock);
 467 
 468         /*
 469          * if there aren't any sockets awaiting connection, then wait for
 470          * one, unless nonblocking
 471          */
 472         while (!(clientsock = sock->iconn)) {
 473                 if (flags & O_NONBLOCK)
 474                         return -EAGAIN;
 475                 interruptible_sleep_on(sock->wait);
 476                 if (current->signal & ~current->blocked) {
 477                         PRINTK("sys_accept: sleep was interrupted\n");
 478                         return -ERESTARTSYS;
 479                 }
 480         }
 481 
 482         /*
 483          * great. finish the connection relative to server and client,
 484          * wake up the client and return the new fd to the server
 485          */
 486         sock->iconn = clientsock->next;
 487         clientsock->next = NULL;
 488         newsock->conn = clientsock;
 489         clientsock->conn = newsock;
 490         clientsock->state = SS_CONNECTED;
 491         newsock->state = SS_CONNECTED;
 492         wake_up(clientsock->wait);
 493         unix_data_ref (UN_DATA(newsock->conn));
 494         UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn);
 495         UN_DATA(newsock)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
 496         UN_DATA(newsock)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
 497         UN_DATA(newsock->conn)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
 498         UN_DATA(newsock->conn)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
 499         return 0;
 500 }
 501 
 502 /*
 503  * gets the current name or the name of the connected socket.
 504  */
 505 static int
 506 unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 507                    int *usockaddr_len, int peer)
 508 {
 509         struct unix_proto_data *upd;
 510         int len;
 511 
 512         PRINTK("unix_proto_getname: socket 0x%x for %s\n", sock,
 513                peer ? "peer" : "self");
 514         if (peer) {
 515                 if (sock->state != SS_CONNECTED) {
 516                         PRINTK("unix_proto_getname: socket not connected\n");
 517                         return -EINVAL;
 518                 }
 519                 upd = UN_DATA(sock->conn);
 520         }
 521         else
 522                 upd = UN_DATA(sock);
 523         verify_area(usockaddr_len, sizeof(*usockaddr_len));
 524         if ((len = get_fs_long(usockaddr_len)) <= 0)
 525                 return -EINVAL;
 526         if (len > upd->sockaddr_len)
 527                 len = upd->sockaddr_len;
 528         if (len) {
 529                 verify_area(usockaddr, len);
 530                 memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
 531         }
 532         put_fs_long(len, usockaddr_len);
 533         return 0;
 534 }
 535 
 536 /*
 537  * we read from our own buf.
 538  */
 539 static int
 540 unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 541 {
 542         struct unix_proto_data *upd;
 543         int todo, avail;
 544 
 545         if ((todo = size) <= 0)
 546                 return 0;
 547         upd = UN_DATA(sock);
 548         while (!(avail = UN_BUF_AVAIL(upd))) {
 549                 if (sock->state != SS_CONNECTED) {
 550                         PRINTK("unix_proto_read: socket not connected\n");
 551                         return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL;
 552                 }
 553                 PRINTK("unix_proto_read: no data available...\n");
 554                 if (nonblock)
 555                         return -EAGAIN;
 556                 interruptible_sleep_on(sock->wait);
 557                 if (current->signal & ~current->blocked) {
 558                         PRINTK("unix_proto_read: interrupted\n");
 559                         return -ERESTARTSYS;
 560                 }
 561                 if (sock->state == SS_DISCONNECTING) {
 562                         PRINTK("unix_proto_read: disconnected\n");
 563                         return 0;
 564                 }
 565         }
 566 
 567         /*
 568          * copy from the read buffer into the user's buffer, watching for
 569          * wraparound. then we wake up the writer
 570          */
 571         do {
 572                 int part, cando;
 573 
 574                 if (avail <= 0) {
 575                         PRINTK("unix_proto_read: AVAIL IS NEGATIVE!!!\n");
 576                         send_sig(SIGKILL,current,1);
 577                         return -EINTR;
 578                 }
 579 
 580                 if ((cando = todo) > avail)
 581                         cando = avail;
 582                 if (cando > (part = BUF_SIZE - upd->bp_tail))
 583                         cando = part;
 584                 PRINTK("unix_proto_read: avail=%d, todo=%d, cando=%d\n",
 585                        avail, todo, cando);
 586                 verify_area(ubuf, cando);
 587                 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
 588                 upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1);
 589                 ubuf += cando;
 590                 todo -= cando;
 591                 if (sock->state == SS_CONNECTED)
 592                         wake_up(sock->conn->wait);
 593                 avail = UN_BUF_AVAIL(upd);
 594         } while (todo && avail);
 595         return size - todo;
 596 }
 597 
 598 /*
 599  * we write to our peer's buf. when we connected we ref'd this peer so we
 600  * are safe that the buffer remains, even after the peer has disconnected,
 601  * which we check other ways.
 602  */
 603 static int
 604 unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
     /* [previous][next][first][last][top][bottom][index][help] */
 605 {
 606         struct unix_proto_data *pupd;
 607         int todo, space;
 608 
 609         if ((todo = size) <= 0)
 610                 return 0;
 611         if (sock->state != SS_CONNECTED) {
 612                 PRINTK("unix_proto_write: socket not connected\n");
 613                 if (sock->state == SS_DISCONNECTING) {
 614                         send_sig(SIGPIPE,current,1);
 615                         return -EINTR;
 616                 }
 617                 return -EINVAL;
 618         }
 619         pupd = UN_DATA(sock)->peerupd;  /* safer than sock->conn */
 620 
 621         while (!(space = UN_BUF_SPACE(pupd))) {
 622                 PRINTK("unix_proto_write: no space left...\n");
 623                 if (nonblock)
 624                         return -EAGAIN;
 625                 interruptible_sleep_on(sock->wait);
 626                 if (current->signal & ~current->blocked) {
 627                         PRINTK("unix_proto_write: interrupted\n");
 628                         return -ERESTARTSYS;
 629                 }
 630                 if (sock->state == SS_DISCONNECTING) {
 631                         PRINTK("unix_proto_write: disconnected (SIGPIPE)\n");
 632                         send_sig(SIGPIPE,current,1);
 633                         return -EINTR;
 634                 }
 635         }
 636 
 637         /*
 638          * copy from the user's buffer to the write buffer, watching for
 639          * wraparound. then we wake up the reader
 640          */
 641         do {
 642                 int part, cando;
 643 
 644                 if (space <= 0) {
 645                         PRINTK("unix_proto_write: SPACE IS NEGATIVE!!!\n");
 646                         send_sig(SIGKILL,current,1);
 647                         return -EINTR;
 648                 }
 649 
 650                 /*
 651                  * we may become disconnected inside this loop, so watch
 652                  * for it (peerupd is safe until we close)
 653                  */
 654                 if (sock->state == SS_DISCONNECTING) {
 655                         send_sig(SIGPIPE,current,1);
 656                         return -EINTR;
 657                 }
 658                 if ((cando = todo) > space)
 659                         cando = space;
 660                 if (cando > (part = BUF_SIZE - pupd->bp_head))
 661                         cando = part;
 662                 PRINTK("unix_proto_write: space=%d, todo=%d, cando=%d\n",
 663                        space, todo, cando);
 664                 verify_area(ubuf, cando);
 665                 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
 666                 pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1);
 667                 ubuf += cando;
 668                 todo -= cando;
 669                 if (sock->state == SS_CONNECTED)
 670                         wake_up(sock->conn->wait);
 671                 space = UN_BUF_SPACE(pupd);
 672         } while (todo && space);
 673         return size - todo;
 674 }
 675 
 676 static int
 677 unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 678 {
 679         struct unix_proto_data *upd, *peerupd;
 680 
 681         /*
 682          * handle server sockets specially
 683          */
 684         if (sock->flags & SO_ACCEPTCON) {
 685                 if (sel_type == SEL_IN) {
 686                         PRINTK("sock_select: %sconnections pending\n",
 687                                sock->iconn ? "" : "no ");
 688                         if (sock->iconn)
 689                                 return 1;
 690                         select_wait(sock->wait, wait);
 691                         return sock->iconn ? 1 : 0;
 692                 }
 693                 PRINTK("sock_select: nothing else for server socket\n");
 694                 select_wait(sock->wait, wait);
 695                 return 0;
 696         }
 697 
 698         if (sel_type == SEL_IN) {
 699                 upd = UN_DATA(sock);
 700                 PRINTK("unix_proto_select: there is%s data available\n",
 701                        UN_BUF_AVAIL(upd) ? "" : " no");
 702                 if (UN_BUF_AVAIL(upd))  /* even if disconnected */
 703                         return 1;
 704                 else if (sock->state != SS_CONNECTED) {
 705                         PRINTK("unix_proto_select: socket not connected (read EOF)\n");
 706                         return 1;
 707                 }
 708                 select_wait(sock->wait,wait);
 709                 return 0;
 710         }
 711         if (sel_type == SEL_OUT) {
 712                 if (sock->state != SS_CONNECTED) {
 713                         PRINTK("unix_proto_select: socket not connected (write EOF)\n");
 714                         return 1;
 715                 }
 716                 peerupd = UN_DATA(sock->conn);
 717                 PRINTK("unix_proto_select: there is%s space available\n",
 718                        UN_BUF_SPACE(peerupd) ? "" : " no");
 719                 if (UN_BUF_SPACE(peerupd) > 0)
 720                         return 1;
 721                 select_wait(sock->wait,wait);
 722                 return 0;
 723         }
 724         /* SEL_EX */
 725         PRINTK("unix_proto_select: there are no exceptions here?!\n");
 726         return 0;
 727 }
 728 
 729 static int
 730 unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 731 {
 732         struct unix_proto_data *upd, *peerupd;
 733 
 734         upd = UN_DATA(sock);
 735         peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
 736 
 737         switch (cmd) {
 738 
 739         case TIOCINQ:
 740                 if (sock->flags & SO_ACCEPTCON)
 741                         return -EINVAL;
 742                 verify_area((void *)arg, sizeof(unsigned long));
 743                 if (UN_BUF_AVAIL(upd) || peerupd)
 744                         put_fs_long(UN_BUF_AVAIL(upd), (unsigned long *)arg);
 745                 else
 746                         put_fs_long(1, (unsigned long *)arg); /* read EOF */
 747                 break;
 748 
 749         case TIOCOUTQ:
 750                 if (sock->flags & SO_ACCEPTCON)
 751                         return -EINVAL;
 752                 verify_area((void *)arg, sizeof(unsigned long));
 753                 if (peerupd)
 754                         put_fs_long(UN_BUF_SPACE(peerupd),
 755                                     (unsigned long *)arg);
 756                 else
 757                         put_fs_long(0, (unsigned long *)arg);
 758                 break;
 759 
 760         default:
 761                 return -EINVAL;
 762         }
 763         return 0;
 764 }
 765 
 766 static int
 767 unix_proto_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 768 {
 769         struct unix_proto_data *upd;
 770 
 771         PRINTK("unix_proto_init: initializing...\n");
 772         for (upd = unix_datas; upd <= last_unix_data; ++upd)
 773                 upd->refcnt = 0;
 774         return 0;
 775 }

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