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

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>
                      6: #include <asm/system.h>
                      7: #include <asm/segment.h>
                      8: #include <sys/socket.h>
                      9: #include <sys/un.h>
                     10: #include <sys/stat.h>
                     11: #include <fcntl.h>
                     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:        unsigned short old_euid;
                    237: 
                    238:        PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock,
                    239:               sockaddr_len);
                    240:        if (sockaddr_len <= UN_PATH_OFFSET ||
                    241:            sockaddr_len >= sizeof(struct sockaddr_un)) {
                    242:                PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len);
                    243:                return -EINVAL;
                    244:        }
                    245:        if (upd->sockaddr_len || upd->inode) {
                    246:                printk("unix_proto_bind: already bound!\n");
                    247:                return -EINVAL;
                    248:        }
                    249:        verify_area(umyaddr, sockaddr_len);
                    250:        memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
                    251:        if (upd->sockaddr_un.sun_family != AF_UNIX) {
                    252:                PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n",
                    253:                       upd->sockaddr_un.sun_family, AF_UNIX);
                    254:                return -EINVAL;
                    255:        }
                    256: 
                    257:        /*
                    258:         *              W A R N I N G
                    259:         * this is a terrible hack. i want to create a socket in the
                    260:         * filesystem and get its inode. sys_mknod() can create one for
                    261:         * me, but it needs superuser privs and doesn't give me the inode.
                    262:         * we fake suser here and get the file created... ugh.
                    263:         */
                    264:        memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
                    265:        fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
                    266:        old_fs = get_fs();
                    267:        set_fs(get_ds());
                    268:        old_euid = current->euid;
                    269:        current->euid = 0;
                    270:        i = sys_mknod(fname, S_IFSOCK, 0);
                    271:        current->euid = old_euid;
                    272:        if (i == 0)
                    273:                i = open_namei(fname, 0, S_IFSOCK, &upd->inode);
                    274:        set_fs(old_fs);
                    275:        if (i < 0) {
                    276:                printk("unix_proto_bind: can't open socket %s\n", fname);
                    277:                return i;
                    278:        }
                    279: 
                    280:        upd->sockaddr_len = sockaddr_len;       /* now its legal */
                    281:        PRINTK("unix_proto_bind: bound socket address: ");
                    282: #ifdef SOCK_DEBUG
                    283:        sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
                    284: #endif
                    285:        return 0;
                    286: }
                    287: 
                    288: /*
                    289:  * perform a connection. we can only connect to unix sockets (i can't for
                    290:  * the life of me find an application where that wouldn't be the case!)
                    291:  */
                    292: static int
                    293: unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
                    294:                   int sockaddr_len)
                    295: {
                    296:        int i;
                    297:        struct unix_proto_data *serv_upd;
                    298:        struct sockaddr_un sockun;
                    299: 
                    300:        PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
                    301:               sockaddr_len);
                    302:        if (sockaddr_len <= UN_PATH_OFFSET ||
                    303:            sockaddr_len >= sizeof(struct sockaddr_un)) {
                    304:                PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len);
                    305:                return -EINVAL;
                    306:        }
                    307:        verify_area(uservaddr, sockaddr_len);
                    308:        memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
                    309:        if (sockun.sun_family != AF_UNIX) {
                    310:                PRINTK("unix_proto_connect: family is %d, not AF_UNIX (%d)\n",
                    311:                       sockun.sun_family, AF_UNIX);
                    312:                return -EINVAL;
                    313:        }
                    314:        if (!(serv_upd = unix_data_lookup(&sockun, sockaddr_len))) {
                    315:                PRINTK("unix_proto_connect: can't locate peer\n");
                    316:                return -EINVAL;
                    317:        }
                    318:        if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
                    319:                PRINTK("unix_proto_connect: can't await connection\n");
                    320:                return i;
                    321:        }
                    322:        unix_data_ref(UN_DATA(sock->conn));
                    323:        UN_DATA(sock)->peerupd = UN_DATA(sock->conn); /* ref server */
                    324:        return 0;
                    325: }
                    326: 
                    327: /*
                    328:  * to do a socketpair, we make just connect the two datas, easy! since we
                    329:  * always wait on the socket inode, they're no contention for a wait area,
                    330:  * and deadlock prevention in the case of a process writing to itself is,
                    331:  * ignored, in true unix fashion!
                    332:  */
                    333: static int
                    334: unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
                    335: {
                    336:        struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
                    337: 
                    338:        unix_data_ref(upd1);
                    339:        unix_data_ref(upd2);
                    340:        upd1->peerupd = upd2;
                    341:        upd2->peerupd = upd1;
                    342:        return 0;
                    343: }
                    344: 
                    345: /*
                    346:  * on accept, we ref the peer's data for safe writes
                    347:  */
                    348: static int
                    349: unix_proto_accept(struct socket *sock, struct socket *newsock)
                    350: {
                    351:        PRINTK("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n",
                    352:               sock, newsock);
                    353:        unix_data_ref(UN_DATA(newsock->conn));
                    354:        UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn);
                    355:        return 0;
                    356: }
                    357: 
                    358: /*
                    359:  * gets the current name or the name of the connected socket.
                    360:  */
                    361: static int
                    362: unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
                    363:                   int *usockaddr_len, int peer)
                    364: {
                    365:        struct unix_proto_data *upd;
                    366:        int len;
                    367: 
                    368:        PRINTK("unix_proto_getname: socket 0x%x for %s\n", sock,
                    369:               peer ? "peer" : "self");
                    370:        if (peer) {
                    371:                if (sock->state != SS_CONNECTED) {
                    372:                        PRINTK("unix_proto_getname: socket not connected\n");
                    373:                        return -EINVAL;
                    374:                }
                    375:                upd = UN_DATA(sock->conn);
                    376:        }
                    377:        else
                    378:                upd = UN_DATA(sock);
                    379:        verify_area(usockaddr_len, sizeof(*usockaddr_len));
                    380:        if ((len = get_fs_long(usockaddr_len)) <= 0)
                    381:                return -EINVAL;
                    382:        if (len > upd->sockaddr_len)
                    383:                len = upd->sockaddr_len;
                    384:        if (len) {
                    385:                verify_area(usockaddr, len);
                    386:                memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
                    387:        }
                    388:        put_fs_long(len, usockaddr_len);
                    389:        return 0;
                    390: }
                    391: 
                    392: /*
                    393:  * we read from our own buf.
                    394:  */
                    395: static int
                    396: unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
                    397: {
                    398:        struct unix_proto_data *upd;
                    399:        int todo, avail;
                    400: 
                    401:        if ((todo = size) <= 0)
                    402:                return 0;
                    403:        upd = UN_DATA(sock);
                    404:        while (!(avail = UN_BUF_AVAIL(upd))) {
                    405:                if (sock->state != SS_CONNECTED) {
                    406:                        PRINTK("unix_proto_read: socket not connected\n");
                    407:                        return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL;
                    408:                }
                    409:                PRINTK("unix_proto_read: no data available...\n");
                    410:                if (nonblock)
                    411:                        return -EAGAIN;
                    412:                interruptible_sleep_on(sock->wait);
                    413:                if (current->signal & ~current->blocked) {
                    414:                        PRINTK("unix_proto_read: interrupted\n");
                    415:                        return -ERESTARTSYS;
                    416:                }
                    417:                if (sock->state == SS_DISCONNECTING) {
                    418:                        PRINTK("unix_proto_read: disconnected\n");
                    419:                        return 0;
                    420:                }
                    421:        }
                    422: 
                    423:        /*
                    424:         * copy from the read buffer into the user's buffer, watching for
                    425:         * wraparound. then we wake up the writer
                    426:         */
                    427:        do {
                    428:                int part, cando;
                    429: 
                    430:                if (avail <= 0) {
                    431:                        PRINTK("unix_proto_read: AVAIL IS NEGATIVE!!!\n");
                    432:                        current->signal |= (1 << (SIGKILL-1));
                    433:                        return -EINTR;
                    434:                }
                    435: 
                    436:                if ((cando = todo) > avail)
                    437:                        cando = avail;
                    438:                if (cando > (part = BUF_SIZE - upd->bp_tail))
                    439:                        cando = part;
                    440:                PRINTK("unix_proto_read: avail=%d, todo=%d, cando=%d\n",
                    441:                       avail, todo, cando);
                    442:                verify_area(ubuf, cando);
                    443:                memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
                    444:                upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1);
                    445:                ubuf += cando;
                    446:                todo -= cando;
                    447:                if (sock->state == SS_CONNECTED)
                    448:                        wake_up(sock->conn->wait);
                    449:                avail = UN_BUF_AVAIL(upd);
                    450:        } while (todo && avail);
                    451:        return size - todo;
                    452: }
                    453: 
                    454: /*
                    455:  * we write to our peer's buf. when we connected we ref'd this peer so we
                    456:  * are safe that the buffer remains, even after the peer has disconnected,
                    457:  * which we check other ways.
                    458:  */
                    459: static int
                    460: unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
                    461: {
                    462:        struct unix_proto_data *pupd;
                    463:        int todo, space;
                    464: 
                    465:        if ((todo = size) <= 0)
                    466:                return 0;
                    467:        if (sock->state != SS_CONNECTED) {
                    468:                PRINTK("unix_proto_write: socket not connected\n");
                    469:                if (sock->state == SS_DISCONNECTING) {
                    470:                        current->signal |= (1 << (SIGPIPE-1));
                    471:                        return -EINTR;
                    472:                }
                    473:                return -EINVAL;
                    474:        }
                    475:        pupd = UN_DATA(sock)->peerupd;  /* safer than sock->conn */
                    476: 
                    477:        while (!(space = UN_BUF_SPACE(pupd))) {
                    478:                PRINTK("unix_proto_write: no space left...\n");
                    479:                if (nonblock)
                    480:                        return 0;
                    481:                interruptible_sleep_on(sock->wait);
                    482:                if (current->signal & ~current->blocked) {
                    483:                        PRINTK("unix_proto_write: interrupted\n");
                    484:                        return -EINTR;
                    485:                }
                    486:                if (sock->state == SS_DISCONNECTING) {
                    487:                        PRINTK("unix_proto_write: disconnected (SIGPIPE)\n");
                    488:                        current->signal |= (1 << (SIGPIPE-1));
                    489:                        return -EINTR;
                    490:                }
                    491:        }
                    492: 
                    493:        /*
                    494:         * copy from the user's buffer to the write buffer, watching for
                    495:         * wraparound. then we wake up the reader
                    496:         */
                    497:        do {
                    498:                int part, cando;
                    499: 
                    500:                if (space <= 0) {
                    501:                        PRINTK("unix_proto_write: SPACE IS NEGATIVE!!!\n");
                    502:                        current->signal |= (1 << (SIGKILL-1));
                    503:                        return -EINTR;
                    504:                }
                    505: 
                    506:                /*
                    507:                 * we may become disconnected inside this loop, so watch
                    508:                 * for it (peerupd is safe until we close)
                    509:                 */
                    510:                if (sock->state == SS_DISCONNECTING) {
                    511:                        current->signal |= (1 << (SIGPIPE-1));
                    512:                        return -EINTR;
                    513:                }
                    514:                if ((cando = todo) > space)
                    515:                        cando = space;
                    516:                if (cando > (part = BUF_SIZE - pupd->bp_head))
                    517:                        cando = part;
                    518:                PRINTK("unix_proto_write: space=%d, todo=%d, cando=%d\n",
                    519:                       space, todo, cando);
                    520:                verify_area(ubuf, cando);
                    521:                memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
                    522:                pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1);
                    523:                ubuf += cando;
                    524:                todo -= cando;
                    525:                if (sock->state == SS_CONNECTED)
                    526:                        wake_up(sock->conn->wait);
                    527:                space = UN_BUF_SPACE(pupd);
                    528:        } while (todo && space);
                    529:        return size - todo;
                    530: }
                    531: 
                    532: static int
                    533: unix_proto_select(struct socket *sock, int which)
                    534: {
                    535:        struct unix_proto_data *upd, *peerupd;
                    536: 
                    537:        if (which == SEL_IN) {
                    538:                upd = UN_DATA(sock);
                    539:                PRINTK("unix_proto_select: there is%s data available\n",
                    540:                       UN_BUF_AVAIL(upd) ? "" : " no");
                    541:                if (UN_BUF_AVAIL(upd))  /* even if disconnected */
                    542:                        return 1;
                    543:                else if (sock->state != SS_CONNECTED) {
                    544:                        PRINTK("unix_proto_select: socket not connected (read EOF)\n");
                    545:                        return 1;
                    546:                }
                    547:                else
                    548:                        return 0;
                    549:        }
                    550:        if (which == SEL_OUT) {
                    551:                if (sock->state != SS_CONNECTED) {
                    552:                        PRINTK("unix_proto_select: socket not connected (write EOF)\n");
                    553:                        return 1;
                    554:                }
                    555:                peerupd = UN_DATA(sock->conn);
                    556:                PRINTK("unix_proto_select: there is%s space available\n",
                    557:                       UN_BUF_SPACE(peerupd) ? "" : " no");
                    558:                return (UN_BUF_SPACE(peerupd) > 0);
                    559:        }
                    560:        /* SEL_EX */
                    561:        PRINTK("unix_proto_select: there are no exceptions here?!\n");
                    562:        return 0;
                    563: }
                    564: 
                    565: static int
                    566: unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                    567: {
                    568:        struct unix_proto_data *upd, *peerupd;
                    569: 
                    570:        upd = UN_DATA(sock);
                    571:        peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
                    572: 
                    573:        switch (cmd) {
                    574:        case TIOCINQ:
                    575:                verify_area((void *)arg, sizeof(unsigned long));
                    576:                if (UN_BUF_AVAIL(upd) || peerupd)
                    577:                        put_fs_long(UN_BUF_AVAIL(upd), (unsigned long *)arg);
                    578:                else
                    579:                        put_fs_long(1, (unsigned long *)arg); /* read EOF */
                    580:                break;
                    581: 
                    582:        case TIOCOUTQ:
                    583:                verify_area((void *)arg, sizeof(unsigned long));
                    584:                if (peerupd)
                    585:                        put_fs_long(UN_BUF_SPACE(peerupd),
                    586:                                    (unsigned long *)arg);
                    587:                else
                    588:                        put_fs_long(0, (unsigned long *)arg);
                    589:                break;
                    590: 
                    591:        default:
                    592:                return -EINVAL;
                    593:        }
                    594:        return 0;
                    595: }
                    596: 
                    597: static int
                    598: unix_proto_init(void)
                    599: {
                    600:        struct unix_proto_data *upd;
                    601: 
                    602:        PRINTK("unix_proto_init: initializing...\n");
                    603:        for (upd = unix_datas; upd <= last_unix_data; ++upd)
                    604:                upd->refcnt = 0;
                    605:        return 0;
                    606: }

unix.superglobalmegacorp.com

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