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

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

unix.superglobalmegacorp.com

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