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

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