Annotation of linux/net/unix.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com