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_data_lookup
  3. unix_data_alloc
  4. unix_data_ref
  5. unix_data_deref
  6. unix_proto_create
  7. unix_proto_dup
  8. unix_proto_release
  9. unix_proto_bind
  10. unix_proto_connect
  11. unix_proto_socketpair
  12. unix_proto_accept
  13. unix_proto_getname
  14. unix_proto_read
  15. unix_proto_write
  16. unix_proto_select
  17. unix_proto_ioctl
  18. unix_proto_init

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

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