Annotation of linux/net/socket.c, revision 1.1.1.4

1.1.1.4 ! root        1: #include <linux/signal.h>
        !             2: #include <linux/errno.h>
1.1       root        3: #include <linux/sched.h>
                      4: #include <linux/kernel.h>
1.1.1.2   root        5: #include <linux/stat.h>
1.1.1.4 ! root        6: #include <linux/socket.h>
        !             7: #include <linux/fcntl.h>
        !             8: #include <linux/termios.h>
        !             9: 
1.1       root       10: #include <asm/system.h>
                     11: #include <asm/segment.h>
1.1.1.4 ! root       12: 
1.1       root       13: #include "kern_sock.h"
                     14: #include "socketcall.h"
                     15: 
                     16: extern int sys_close(int fd);
                     17: 
                     18: extern struct proto_ops unix_proto_ops;
                     19: 
                     20: static struct {
                     21:        short family;
                     22:        char *name;
                     23:        struct proto_ops *ops;
                     24: } proto_table[] = {
                     25:        AF_UNIX,        "AF_UNIX",      &unix_proto_ops
                     26: };
                     27: #define NPROTO (sizeof(proto_table) / sizeof(proto_table[0]))
                     28: 
                     29: static char *
                     30: family_name(int family)
                     31: {
                     32:        int i;
                     33: 
                     34:        for (i = 0; i < NPROTO; ++i)
                     35:                if (proto_table[i].family == family)
                     36:                        return proto_table[i].name;
                     37:        return "UNKNOWN";
                     38: }
                     39: 
                     40: static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
                     41:                      int whence);
                     42: static int sock_read(struct inode *inode, struct file *file, char *buf,
                     43:                     int size);
                     44: static int sock_write(struct inode *inode, struct file *file, char *buf,
                     45:                      int size);
                     46: static int sock_readdir(struct inode *inode, struct file *file,
                     47:                        struct dirent *dirent, int count);
                     48: static void sock_close(struct inode *inode, struct file *file);
1.1.1.4 ! root       49: static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
1.1       root       50: static int sock_ioctl(struct inode *inode, struct file *file,
                     51:                      unsigned int cmd, unsigned int arg);
                     52: 
                     53: static struct file_operations socket_file_ops = {
                     54:        sock_lseek,
                     55:        sock_read,
                     56:        sock_write,
                     57:        sock_readdir,
                     58:        sock_select,    /* not in vfs yet */
                     59:        sock_ioctl,
                     60:        NULL,           /* no special open code... */
                     61:        sock_close
                     62: };
                     63: 
                     64: #define SOCK_INODE(S) ((struct inode *)(S)->dummy)
                     65: 
                     66: static struct socket sockets[NSOCKETS];
                     67: #define last_socket (sockets + NSOCKETS - 1)
1.1.1.4 ! root       68: static struct wait_queue *socket_wait_free = NULL;
1.1       root       69: 
                     70: /*
                     71:  * obtains the first available file descriptor and sets it up for use
                     72:  */
                     73: static int
                     74: get_fd(struct inode *inode)
                     75: {
                     76:        int fd, i;
                     77:        struct file *file;
                     78: 
                     79:        /*
                     80:         * find a file descriptor suitable for return to the user.
                     81:         */
                     82:        for (fd = 0; fd < NR_OPEN; ++fd)
                     83:                if (!current->filp[fd])
                     84:                        break;
                     85:        if (fd == NR_OPEN)
                     86:                return -1;
                     87:        current->close_on_exec &= ~(1 << fd);
                     88:        for (file = file_table, i = 0; i < NR_FILE; ++i, ++file)
                     89:                if (!file->f_count)
                     90:                        break;
                     91:        if (i == NR_FILE)
                     92:                return -1;
                     93:        current->filp[fd] = file;
                     94:        file->f_op = &socket_file_ops;
                     95:        file->f_mode = 3;
                     96:        file->f_flags = 0;
                     97:        file->f_count = 1;
                     98:        file->f_inode = inode;
                     99:        file->f_pos = 0;
                    100:        return fd;
                    101: }
                    102: 
                    103: /*
                    104:  * reverses the action of get_fd() by releasing the file. it closes the
                    105:  * descriptor, but makes sure it does nothing more. called when an incomplete
                    106:  * socket must be closed, along with sock_release().
                    107:  */
                    108: static inline void
                    109: toss_fd(int fd)
                    110: {
                    111:        current->filp[fd]->f_inode = NULL;      /* safe from iput */
                    112:        sys_close(fd);
                    113: }
                    114: 
                    115: static inline struct socket *
                    116: socki_lookup(struct inode *inode)
                    117: {
                    118:        struct socket *sock;
                    119: 
                    120:        for (sock = sockets; sock <= last_socket; ++sock)
                    121:                if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
                    122:                        return sock;
                    123:        return NULL;
                    124: }
                    125: 
                    126: static inline struct socket *
                    127: sockfd_lookup(int fd, struct file **pfile)
                    128: {
                    129:        struct file *file;
                    130: 
                    131:        if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd]))
                    132:                return NULL;
                    133:        if (pfile)
                    134:                *pfile = file;
                    135:        return socki_lookup(file->f_inode);
                    136: }
                    137: 
                    138: static struct socket *
                    139: sock_alloc(int wait)
                    140: {
                    141:        struct socket *sock;
                    142: 
                    143:        while (1) {
                    144:                cli();
                    145:                for (sock = sockets; sock <= last_socket; ++sock)
                    146:                        if (sock->state == SS_FREE) {
                    147:                                sock->state = SS_UNCONNECTED;
                    148:                                sti();
                    149:                                sock->flags = 0;
                    150:                                sock->ops = NULL;
                    151:                                sock->data = NULL;
                    152:                                sock->conn = NULL;
                    153:                                sock->iconn = NULL;
                    154:                                /*
                    155:                                 * this really shouldn't be necessary, but
                    156:                                 * everything else depends on inodes, so we
                    157:                                 * grab it.
                    158:                                 * sleeps are also done on the i_wait member
                    159:                                 * of this inode.
                    160:                                 * the close system call will iput this inode
                    161:                                 * for us.
                    162:                                 */
                    163:                                if (!(SOCK_INODE(sock) = get_empty_inode())) {
                    164:                                        printk("sock_alloc: no more inodes\n");
                    165:                                        sock->state = SS_FREE;
                    166:                                        return NULL;
                    167:                                }
                    168:                                SOCK_INODE(sock)->i_mode = S_IFSOCK;
                    169:                                sock->wait = &SOCK_INODE(sock)->i_wait;
                    170:                                PRINTK("sock_alloc: socket 0x%x, inode 0x%x\n",
                    171:                                       sock, SOCK_INODE(sock));
                    172:                                return sock;
                    173:                        }
                    174:                sti();
                    175:                if (!wait)
                    176:                        return NULL;
                    177:                PRINTK("sock_alloc: no free sockets, sleeping...\n");
                    178:                interruptible_sleep_on(&socket_wait_free);
                    179:                if (current->signal & ~current->blocked) {
                    180:                        PRINTK("sock_alloc: sleep was interrupted\n");
                    181:                        return NULL;
                    182:                }
                    183:                PRINTK("sock_alloc: wakeup... trying again...\n");
                    184:        }
                    185: }
                    186: 
                    187: static inline void
                    188: sock_release_peer(struct socket *peer)
                    189: {
                    190:        peer->state = SS_DISCONNECTING;
                    191:        wake_up(peer->wait);
                    192: }
                    193: 
                    194: static void
                    195: sock_release(struct socket *sock)
                    196: {
                    197:        int oldstate;
                    198:        struct socket *peersock, *nextsock;
                    199: 
                    200:        PRINTK("sock_release: socket 0x%x, inode 0x%x\n", sock,
                    201:               SOCK_INODE(sock));
                    202:        if ((oldstate = sock->state) != SS_UNCONNECTED)
                    203:                sock->state = SS_DISCONNECTING;
                    204:        /*
                    205:         * wake up anyone waiting for connections
                    206:         */
                    207:        for (peersock = sock->iconn; peersock; peersock = nextsock) {
                    208:                nextsock = peersock->next;
                    209:                sock_release_peer(peersock);
                    210:        }
                    211:        /*
                    212:         * wake up anyone we're connected to. first, we release the
                    213:         * protocol, to give it a chance to flush data, etc.
                    214:         */
                    215:        peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
                    216:        if (sock->ops)
                    217:                sock->ops->release(sock, peersock);
                    218:        if (peersock)
                    219:                sock_release_peer(peersock);
                    220:        sock->state = SS_FREE;          /* this really releases us */
                    221:        wake_up(&socket_wait_free);
                    222: }
                    223: 
                    224: static int
                    225: sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
                    226: {
                    227:        PRINTK("sock_lseek: huh?\n");
                    228:        return -EBADF;
                    229: }
                    230: 
                    231: static int
                    232: sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
                    233: {
                    234:        struct socket *sock;
                    235: 
                    236:        PRINTK("sock_read: buf=0x%x, size=%d\n", ubuf, size);
                    237:        if (!(sock = socki_lookup(inode))) {
                    238:                printk("sock_read: can't find socket for inode!\n");
                    239:                return -EBADF;
                    240:        }
                    241:        if (sock->flags & SO_ACCEPTCON)
                    242:                return -EINVAL;
                    243:        return sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK));
                    244: }
                    245: 
                    246: static int
                    247: sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
                    248: {
                    249:        struct socket *sock;
                    250: 
                    251:        PRINTK("sock_write: buf=0x%x, size=%d\n", ubuf, size);
                    252:        if (!(sock = socki_lookup(inode))) {
                    253:                printk("sock_write: can't find socket for inode!\n");
                    254:                return -EBADF;
                    255:        }
                    256:        if (sock->flags & SO_ACCEPTCON)
                    257:                return -EINVAL;
                    258:        return sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK));
                    259: }
                    260: 
                    261: static int
                    262: sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
                    263:             int count)
                    264: {
                    265:        PRINTK("sock_readdir: huh?\n");
                    266:        return -EBADF;
                    267: }
                    268: 
                    269: int
                    270: sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                    271:           unsigned int arg)
                    272: {
                    273:        struct socket *sock;
                    274: 
                    275:        PRINTK("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg);
                    276:        if (!(sock = socki_lookup(inode))) {
                    277:                printk("sock_ioctl: can't find socket for inode!\n");
                    278:                return -EBADF;
                    279:        }
                    280:        switch (cmd) {
                    281:        case TIOCINQ:
                    282:        case TIOCOUTQ:
                    283:                if (sock->flags & SO_ACCEPTCON)
                    284:                        return -EINVAL;
                    285:                break;
                    286: 
                    287:        default:
                    288:                return -EINVAL;
                    289:        }
                    290:        return sock->ops->ioctl(sock, cmd, arg);
                    291: }
                    292: 
1.1.1.4 ! root      293: static int
        !           294: sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
1.1       root      295: {
                    296:        struct socket *sock;
                    297: 
                    298:        PRINTK("sock_select: inode = 0x%x, kind = %s\n", inode,
1.1.1.4 ! root      299:               (sel_type == SEL_IN) ? "in" :
        !           300:               (sel_type == SEL_OUT) ? "out" : "ex");
1.1       root      301:        if (!(sock = socki_lookup(inode))) {
1.1.1.4 ! root      302:                printk("sock_select: can't find socket for inode!\n");
        !           303:                return 0;
1.1       root      304:        }
                    305: 
                    306:        /*
                    307:         * handle server sockets specially
                    308:         */
                    309:        if (sock->flags & SO_ACCEPTCON) {
1.1.1.4 ! root      310:                if (sel_type == SEL_IN) {
1.1       root      311:                        PRINTK("sock_select: %sconnections pending\n",
                    312:                               sock->iconn ? "" : "no ");
1.1.1.4 ! root      313:                        if (sock->iconn)
        !           314:                                return 1;
        !           315:                        select_wait(&inode->i_wait, wait);
1.1       root      316:                        return sock->iconn ? 1 : 0;
                    317:                }
                    318:                PRINTK("sock_select: nothing else for server socket\n");
1.1.1.4 ! root      319:                select_wait(&inode->i_wait, wait);
1.1       root      320:                return 0;
                    321:        }
                    322:        /*
                    323:         * we can't return errors to select, so its either yes or no.
                    324:         */
1.1.1.4 ! root      325:        if (sock->ops && sock->ops->select)
        !           326:                return sock->ops->select(sock, sel_type, wait);
        !           327:        return 0;
1.1       root      328: }
                    329: 
                    330: void
                    331: sock_close(struct inode *inode, struct file *file)
                    332: {
                    333:        struct socket *sock;
                    334: 
                    335:        PRINTK("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count);
                    336:        /*
                    337:         * it's possible the inode is NULL if we're closing an unfinished
                    338:         * socket.
                    339:         */
                    340:        if (!inode)
                    341:                return;
                    342:        if (!(sock = socki_lookup(inode))) {
                    343:                printk("sock_close: can't find socket for inode!\n");
                    344:                return;
                    345:        }
                    346:        sock_release(sock);
                    347: }
                    348: 
                    349: int
                    350: sock_awaitconn(struct socket *mysock, struct socket *servsock)
                    351: {
                    352:        struct socket *last;
                    353: 
                    354:        PRINTK("sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
                    355:               mysock, servsock);
                    356:        if (!(servsock->flags & SO_ACCEPTCON)) {
                    357:                PRINTK("sock_awaitconn: server not accepting connections\n");
                    358:                return -EINVAL;
                    359:        }
                    360: 
                    361:        /*
                    362:         * put ourselves on the server's incomplete connection queue.
                    363:         */
                    364:        mysock->next = NULL;
                    365:        cli();
                    366:        if (!(last = servsock->iconn))
                    367:                servsock->iconn = mysock;
                    368:        else {
                    369:                while (last->next)
                    370:                        last = last->next;
                    371:                last->next = mysock;
                    372:        }
                    373:        mysock->state = SS_CONNECTING;
                    374:        mysock->conn = servsock;
                    375:        sti();
                    376: 
                    377:        /*
                    378:         * wake up server, then await connection. server will set state to
                    379:         * SS_CONNECTED if we're connected.
                    380:         */
                    381:        wake_up(servsock->wait);
                    382:        if (mysock->state != SS_CONNECTED) {
                    383:                interruptible_sleep_on(mysock->wait);
                    384:                if (mysock->state != SS_CONNECTED) {
                    385:                        /*
                    386:                         * if we're not connected we could have been
                    387:                         * 1) interrupted, so we need to remove ourselves
                    388:                         *    from the server list
                    389:                         * 2) rejected (mysock->conn == NULL), and have
                    390:                         *    already been removed from the list
                    391:                         */
                    392:                        if (mysock->conn == servsock) {
                    393:                                cli();
                    394:                                if ((last = servsock->iconn) == mysock)
                    395:                                        servsock->iconn = mysock->next;
                    396:                                else {
                    397:                                        while (last->next != mysock)
                    398:                                                last = last->next;
                    399:                                        last->next = mysock->next;
                    400:                                }
                    401:                                sti();
                    402:                        }
                    403:                        return mysock->conn ? -EINTR : -EACCES;
                    404:                }
                    405:        }
                    406:        return 0;
                    407: }
                    408: 
                    409: /*
                    410:  * perform the socket system call. we locate the appropriate family, then
                    411:  * create a fresh socket.
                    412:  */
                    413: static int
                    414: sock_socket(int family, int type, int protocol)
                    415: {
                    416:        int i, fd;
                    417:        struct socket *sock;
                    418:        struct proto_ops *ops;
                    419: 
                    420:        PRINTK("sys_socket: family = %d (%s), type = %d, protocol = %d\n",
                    421:               family, family_name(family), type, protocol);
                    422: 
                    423:        /*
                    424:         * locate the correct protocol family
                    425:         */
                    426:        for (i = 0; i < NPROTO; ++i)
                    427:                if (proto_table[i].family == family)
                    428:                        break;
                    429:        if (i == NPROTO) {
                    430:                PRINTK("sys_socket: family not found\n");
                    431:                return -EINVAL;
                    432:        }
                    433:        ops = proto_table[i].ops;
                    434: 
                    435:        /*
                    436:         * check that this is a type that we know how to manipulate and
                    437:         * the protocol makes sense here. the family can still reject the
                    438:         * protocol later.
                    439:         */
                    440:        if ((type != SOCK_STREAM &&
                    441:             type != SOCK_DGRAM &&
                    442:             type != SOCK_SEQPACKET &&
                    443:             type != SOCK_RAW) ||
                    444:            protocol < 0)
                    445:                return -EINVAL;
                    446: 
                    447:        /*
                    448:         * allocate the socket and allow the family to set things up. if
                    449:         * the protocol is 0, the family is instructed to select an appropriate
                    450:         * default.
                    451:         */
                    452:        if (!(sock = sock_alloc(1))) {
                    453:                printk("sys_socket: no more sockets\n");
                    454:                return -EAGAIN;
                    455:        }
                    456:        sock->type = type;
                    457:        sock->ops = ops;
                    458:        if ((i = sock->ops->create(sock, protocol)) < 0) {
                    459:                sock_release(sock);
                    460:                return i;
                    461:        }
                    462: 
                    463:        if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
                    464:                sock_release(sock);
                    465:                return -EINVAL;
                    466:        }
                    467: 
                    468:        return fd;
                    469: }
                    470: 
                    471: static int
                    472: sock_socketpair(int family, int type, int protocol, int usockvec[2])
                    473: {
                    474:        int fd1, fd2, i;
                    475:        struct socket *sock1, *sock2;
                    476: 
                    477:        PRINTK("sys_socketpair: family = %d, type = %d, protocol = %d\n",
                    478:               family, type, protocol);
                    479: 
                    480:        /*
                    481:         * obtain the first socket and check if the underlying protocol
                    482:         * supports the socketpair call
                    483:         */
                    484:        if ((fd1 = sock_socket(family, type, protocol)) < 0)
                    485:                return fd1;
                    486:        sock1 = sockfd_lookup(fd1, NULL);
                    487:        if (!sock1->ops->socketpair) {
                    488:                sys_close(fd1);
                    489:                return -EINVAL;
                    490:        }
                    491: 
                    492:        /*
                    493:         * now grab another socket and try to connect the two together
                    494:         */
                    495:        if ((fd2 = sock_socket(family, type, protocol)) < 0) {
                    496:                sys_close(fd1);
                    497:                return -EINVAL;
                    498:        }
                    499:        sock2 = sockfd_lookup(fd2, NULL);
                    500:        if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
                    501:                sys_close(fd1);
                    502:                sys_close(fd2);
                    503:                return i;
                    504:        }
                    505:        sock1->conn = sock2;
                    506:        sock2->conn = sock1;
                    507:        sock1->state = SS_CONNECTED;
                    508:        sock2->state = SS_CONNECTED;
                    509: 
                    510:        verify_area(usockvec, 2 * sizeof(int));
                    511:        put_fs_long(fd1, &usockvec[0]);
                    512:        put_fs_long(fd2, &usockvec[1]);
                    513: 
                    514:        return 0;
                    515: }
                    516: 
                    517: /*
                    518:  * binds a name to a socket. nothing much to do here since its the
                    519:  * protocol's responsibility to handle the local address
                    520:  */
                    521: static int
                    522: sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
                    523: {
                    524:        struct socket *sock;
                    525:        int i;
                    526: 
                    527:        PRINTK("sys_bind: fd = %d\n", fd);
                    528:        if (!(sock = sockfd_lookup(fd, NULL)))
                    529:                return -EBADF;
                    530:        if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
                    531:                PRINTK("sys_bind: bind failed\n");
                    532:                return i;
                    533:        }
                    534:        return 0;
                    535: }
                    536: 
                    537: /*
                    538:  * perform a listen. basically, we allow the protocol to do anything
                    539:  * necessary for a listen, and if that works, we mark the socket as
                    540:  * ready for listening.
                    541:  */
                    542: static int
                    543: sock_listen(int fd, int backlog)
                    544: {
                    545:        struct socket *sock;
                    546: 
                    547:        PRINTK("sys_listen: fd = %d\n", fd);
                    548:        if (!(sock = sockfd_lookup(fd, NULL)))
                    549:                return -EBADF;
                    550:        if (sock->state != SS_UNCONNECTED) {
                    551:                PRINTK("sys_listen: socket isn't unconnected\n");
                    552:                return -EINVAL;
                    553:        }
                    554:        if (sock->flags & SO_ACCEPTCON) {
                    555:                PRINTK("sys_listen: socket already accepting connections!\n");
                    556:                return -EINVAL;
                    557:        }
                    558:        sock->flags |= SO_ACCEPTCON;
                    559:        return 0;
                    560: }
                    561: 
                    562: /*
                    563:  * for accept, we attempt to create a new socket, set up the link with the
                    564:  * client, wake up the client, then return the new connected fd.
                    565:  */
                    566: static int
                    567: sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
                    568: {
                    569:        struct file *file;
                    570:        struct socket *sock, *clientsock, *newsock;
                    571:        int i;
                    572: 
                    573:        PRINTK("sys_accept: fd = %d\n", fd);
                    574:        if (!(sock = sockfd_lookup(fd, &file)))
                    575:                return -EBADF;
                    576:        if (sock->state != SS_UNCONNECTED) {
                    577:                PRINTK("sys_accept: socket isn't unconnected\n");
                    578:                return -EINVAL;
                    579:        }
                    580:        if (!(sock->flags & SO_ACCEPTCON)) {
                    581:                PRINTK("sys_accept: socket not accepting connections!\n");
                    582:                return -EINVAL;
                    583:        }
                    584: 
                    585:        /*
                    586:         * if there aren't any sockets awaiting connection, then wait for
                    587:         * one, unless nonblocking
                    588:         */
                    589:        while (!(clientsock = sock->iconn)) {
                    590:                if (file->f_flags & O_NONBLOCK)
                    591:                        return -EAGAIN;
                    592:                interruptible_sleep_on(sock->wait);
                    593:                if (current->signal & ~current->blocked) {
                    594:                        PRINTK("sys_accept: sleep was interrupted\n");
1.1.1.3   root      595:                        return -ERESTARTSYS;
1.1       root      596:                }
                    597:        }
                    598: 
                    599:        if (!(newsock = sock_alloc(0))) {
                    600:                printk("sys_accept: no more sockets\n");
                    601:                return -EINVAL;
                    602:        }
                    603:        newsock->type = sock->type;
                    604:        newsock->ops = sock->ops;
                    605:        if ((i = sock->ops->dup(newsock, sock)) < 0) {
                    606:                sock_release(newsock);
                    607:                return i;
                    608:        }
                    609: 
                    610:        if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
                    611:                sock_release(newsock);
                    612:                return -EINVAL;
                    613:        }
                    614: 
                    615:        /*
                    616:         * great. finish the connection relative to server and client,
                    617:         * wake up the client and return the new fd to the server
                    618:         */
                    619:        sock->iconn = clientsock->next;
                    620:        clientsock->next = NULL;
                    621:        newsock->conn = clientsock;
                    622:        clientsock->conn = newsock;
                    623:        clientsock->state = SS_CONNECTED;
                    624:        newsock->state = SS_CONNECTED;
                    625:        newsock->ops->accept(sock, newsock);
                    626:        PRINTK("sys_accept: connected socket 0x%x via 0x%x to 0x%x\n",
                    627:               sock, newsock, clientsock);
                    628:        if (upeer_sockaddr)
                    629:                newsock->ops->getname(newsock, upeer_sockaddr,
                    630:                                      upeer_addrlen, 1);
                    631:        wake_up(clientsock->wait);
                    632: 
                    633:        return fd;
                    634: }
                    635: 
                    636: /*
                    637:  * attempt to connect to a socket with the server address.
                    638:  */
                    639: static int
                    640: sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
                    641: {
                    642:        struct socket *sock;
                    643:        int i;
                    644: 
                    645:        PRINTK("sys_connect: fd = %d\n", fd);
                    646:        if (!(sock = sockfd_lookup(fd, NULL)))
                    647:                return -EBADF;
                    648:        if (sock->state != SS_UNCONNECTED) {
                    649:                PRINTK("sys_connect: socket not unconnected\n");
                    650:                return -EINVAL;
                    651:        }
                    652:        if ((i = sock->ops->connect(sock, uservaddr, addrlen)) < 0) {
                    653:                PRINTK("sys_connect: connect failed\n");
                    654:                return i;
                    655:        }
                    656:        return 0;
                    657: }
                    658: 
                    659: static int
                    660: sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
                    661: {
                    662:        struct socket *sock;
                    663: 
                    664:        PRINTK("sys_getsockname: fd = %d\n", fd);
                    665:        if (!(sock = sockfd_lookup(fd, NULL)))
                    666:                return -EBADF;
                    667:        return sock->ops->getname(sock, usockaddr, usockaddr_len, 0);
                    668: }
                    669: 
                    670: static int
                    671: sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
                    672: {
                    673:        struct socket *sock;
                    674: 
                    675:        PRINTK("sys_getpeername: fd = %d\n", fd);
                    676:        if (!(sock = sockfd_lookup(fd, NULL)))
                    677:                return -EBADF;
                    678:        return sock->ops->getname(sock, usockaddr, usockaddr_len, 1);
                    679: }
                    680: 
                    681: /*
                    682:  * system call vectors. since i want to rewrite sockets as streams, we have
                    683:  * this level of indirection. not a lot of overhead, since more of the work is
                    684:  * done via read/write/select directly
                    685:  */
                    686: int
                    687: sys_socketcall(int call, unsigned long *args)
                    688: {
                    689:        switch (call) {
                    690:        case SYS_SOCKET:
                    691:                verify_area(args, 3 * sizeof(long));
                    692:                return sock_socket(get_fs_long(args+0),
                    693:                                   get_fs_long(args+1),
                    694:                                   get_fs_long(args+2));
                    695: 
                    696:        case SYS_BIND:
                    697:                verify_area(args, 3 * sizeof(long));
                    698:                return sock_bind(get_fs_long(args+0),
                    699:                                 (struct sockaddr *)get_fs_long(args+1),
                    700:                                 get_fs_long(args+2));
                    701: 
                    702:        case SYS_CONNECT:
                    703:                verify_area(args, 3 * sizeof(long));
                    704:                return sock_connect(get_fs_long(args+0),
                    705:                                    (struct sockaddr *)get_fs_long(args+1),
                    706:                                    get_fs_long(args+2));
                    707: 
                    708:        case SYS_LISTEN:
                    709:                verify_area(args, 2 * sizeof(long));
                    710:                return sock_listen(get_fs_long(args+0),
                    711:                                   get_fs_long(args+1));
                    712: 
                    713:        case SYS_ACCEPT:
                    714:                verify_area(args, 3 * sizeof(long));
                    715:                return sock_accept(get_fs_long(args+0),
                    716:                                   (struct sockaddr *)get_fs_long(args+1),
                    717:                                   (int *)get_fs_long(args+2));
                    718: 
                    719:        case SYS_GETSOCKNAME:
                    720:                verify_area(args, 3 * sizeof(long));
                    721:                return sock_getsockname(get_fs_long(args+0),
                    722:                                        (struct sockaddr *)get_fs_long(args+1),
                    723:                                        (int *)get_fs_long(args+2));
                    724: 
                    725:        case SYS_GETPEERNAME:
                    726:                verify_area(args, 3 * sizeof(long));
                    727:                return sock_getpeername(get_fs_long(args+0),
                    728:                                        (struct sockaddr *)get_fs_long(args+1),
                    729:                                        (int *)get_fs_long(args+2));
                    730: 
                    731:        case SYS_SOCKETPAIR:
                    732:                verify_area(args, 4 * sizeof(long));
                    733:                return sock_socketpair(get_fs_long(args+0),
                    734:                                       get_fs_long(args+1),
                    735:                                       get_fs_long(args+2),
                    736:                                       (int *)get_fs_long(args+3));
                    737: 
                    738:        default:
                    739:                return -EINVAL;
                    740:        }
                    741: }
                    742: 
                    743: void
                    744: sock_init(void)
                    745: {
                    746:        struct socket *sock;
                    747:        int i, ok;
                    748: 
                    749:        for (sock = sockets; sock <= last_socket; ++sock)
                    750:                sock->state = SS_FREE;
                    751:        for (i = ok = 0; i < NPROTO; ++i) {
                    752:                printk("sock_init: initializing family %d (%s)\n",
                    753:                       proto_table[i].family, proto_table[i].name);
                    754:                if ((*proto_table[i].ops->init)() < 0) {
                    755:                        printk("sock_init: init failed.\n",
                    756:                               proto_table[i].family);
                    757:                        proto_table[i].family = -1;
                    758:                }
                    759:                else
                    760:                        ++ok;
                    761:        }
                    762:        if (!ok)
                    763:                printk("sock_init: warning: no protocols initialized\n");
                    764:        return;
                    765: }
                    766: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.