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

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

unix.superglobalmegacorp.com

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