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

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

unix.superglobalmegacorp.com

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