Annotation of linux/fs/pipe.c, revision 1.1.1.9

1.1.1.2   root        1: /*
                      2:  *  linux/fs/pipe.c
                      3:  *
1.1.1.9 ! root        4:  *  Copyright (C) 1991, 1992  Linus Torvalds
1.1.1.2   root        5:  */
                      6: 
1.1       root        7: #include <asm/segment.h>
1.1.1.6   root        8: 
                      9: #include <linux/sched.h>
1.1.1.3   root       10: #include <linux/kernel.h>
1.1.1.9 ! root       11: #include <linux/errno.h>
        !            12: #include <linux/signal.h>
        !            13: #include <linux/fcntl.h>
        !            14: #include <linux/termios.h>
1.1       root       15: 
1.1.1.6   root       16: static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
1.1       root       17: {
1.1.1.2   root       18:        int chars, size, read = 0;
1.1       root       19: 
1.1.1.4   root       20:        if (!(filp->f_flags & O_NONBLOCK))
                     21:                while (!PIPE_SIZE(*inode)) {
1.1.1.3   root       22:                        wake_up(& PIPE_WRITE_WAIT(*inode));
1.1.1.8   root       23:                        if (!PIPE_WRITERS(*inode)) /* are there any writers? */
1.1.1.4   root       24:                                return 0;
1.1.1.3   root       25:                        if (current->signal & ~current->blocked)
1.1.1.4   root       26:                                return -ERESTARTSYS;
1.1.1.3   root       27:                        interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
1.1.1.2   root       28:                }
1.1.1.4   root       29:        while (count>0 && (size = PIPE_SIZE(*inode))) {
1.1.1.2   root       30:                chars = PAGE_SIZE-PIPE_TAIL(*inode);
                     31:                if (chars > count)
                     32:                        chars = count;
                     33:                if (chars > size)
                     34:                        chars = size;
1.1.1.8   root       35:                memcpy_tofs(buf, (char *)inode->i_size+PIPE_TAIL(*inode), chars );
1.1.1.2   root       36:                read += chars;
                     37:                PIPE_TAIL(*inode) += chars;
                     38:                PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
1.1.1.8   root       39:                count -= chars;
                     40:                buf += chars;
1.1       root       41:        }
1.1.1.3   root       42:        wake_up(& PIPE_WRITE_WAIT(*inode));
1.1.1.5   root       43:        return read?read:-EAGAIN;
1.1       root       44: }
                     45:        
1.1.1.6   root       46: static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
1.1       root       47: {
1.1.1.2   root       48:        int chars, size, written = 0;
1.1       root       49: 
1.1.1.8   root       50:        if (!PIPE_READERS(*inode)) { /* no readers */
1.1.1.7   root       51:                send_sig(SIGPIPE,current,0);
1.1.1.8   root       52:                return -EPIPE;
1.1.1.7   root       53:        }
1.1.1.8   root       54: /* if count < PAGE_SIZE, we have to make it atomic */
                     55:        if (count < PAGE_SIZE)
                     56:                size = PAGE_SIZE-count;
                     57:        else
                     58:                size = PAGE_SIZE-1;
1.1.1.2   root       59:        while (count>0) {
1.1.1.8   root       60:                while (PIPE_SIZE(*inode) >= size) {
                     61:                        if (!PIPE_READERS(*inode)) { /* no readers */
1.1.1.7   root       62:                                send_sig(SIGPIPE,current,0);
1.1.1.8   root       63:                                return written?written:-EPIPE;
1.1       root       64:                        }
1.1.1.4   root       65:                        if (current->signal & ~current->blocked)
1.1.1.8   root       66:                                return written?written:-ERESTARTSYS;
                     67:                        if (filp->f_flags & O_NONBLOCK)
                     68:                                return -EAGAIN;
                     69:                        else
                     70:                                interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
1.1       root       71:                }
1.1.1.8   root       72:                while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
                     73:                        chars = PAGE_SIZE-PIPE_HEAD(*inode);
                     74:                        if (chars > count)
                     75:                                chars = count;
                     76:                        if (chars > size)
                     77:                                chars = size;
                     78:                        memcpy_fromfs((char *)inode->i_size+PIPE_HEAD(*inode), buf, chars );
                     79:                        written += chars;
                     80:                        PIPE_HEAD(*inode) += chars;
                     81:                        PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
                     82:                        count -= chars;
                     83:                        buf += chars;
                     84:                }
                     85:                wake_up(& PIPE_READ_WAIT(*inode));
                     86:                size = PAGE_SIZE-1;
1.1       root       87:        }
1.1.1.2   root       88:        return written;
1.1       root       89: }
                     90: 
1.1.1.6   root       91: static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
                     92: {
                     93:        return -ESPIPE;
                     94: }
                     95: 
                     96: static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
                     97: {
                     98:        return -ENOTDIR;
                     99: }
                    100: 
                    101: static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
                    102: {
                    103:        return -EBADF;
                    104: }
                    105: 
                    106: static int pipe_ioctl(struct inode *pino, struct file * filp,
                    107:        unsigned int cmd, unsigned int arg)
                    108: {
                    109:        switch (cmd) {
                    110:                case FIONREAD:
                    111:                        verify_area((void *) arg,4);
                    112:                        put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
                    113:                        return 0;
                    114:                default:
                    115:                        return -EINVAL;
                    116:        }
                    117: }
                    118: 
1.1.1.9 ! root      119: static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
        !           120: {
        !           121:        switch (sel_type) {
        !           122:                case SEL_IN:
        !           123:                        if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
        !           124:                                return 1;
        !           125:                        select_wait(&PIPE_READ_WAIT(*inode), wait);
        !           126:                        return 0;
        !           127:                case SEL_OUT:
        !           128:                        if (!PIPE_FULL(*inode) || !PIPE_WRITERS(*inode))
        !           129:                                return 1;
        !           130:                        select_wait(&PIPE_WRITE_WAIT(*inode), wait);
        !           131:                        return 0;
        !           132:                case SEL_EX:
        !           133:                        if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
        !           134:                                return 1;
        !           135:                        select_wait(&inode->i_wait,wait);
        !           136:                        return 0;
        !           137:        }
        !           138:        return 0;
        !           139: }
        !           140: 
1.1.1.6   root      141: /*
1.1.1.8   root      142:  * Ok, these three routines NOW keep track of readers/writers,
                    143:  * Linus previously did it with inode->i_count checking.
1.1.1.6   root      144:  */
                    145: static void pipe_read_release(struct inode * inode, struct file * filp)
                    146: {
1.1.1.8   root      147:        PIPE_READERS(*inode)--;
                    148:        wake_up(&PIPE_WRITE_WAIT(*inode));
1.1.1.6   root      149: }
                    150: 
                    151: static void pipe_write_release(struct inode * inode, struct file * filp)
                    152: {
1.1.1.8   root      153:        PIPE_WRITERS(*inode)--;
                    154:        wake_up(&PIPE_READ_WAIT(*inode));
                    155: }
                    156: 
                    157: static void pipe_rdwr_release(struct inode * inode, struct file * filp)
                    158: {
                    159:        PIPE_READERS(*inode)--;
                    160:        PIPE_WRITERS(*inode)--;
                    161:        wake_up(&PIPE_READ_WAIT(*inode));
                    162:        wake_up(&PIPE_WRITE_WAIT(*inode));
1.1.1.6   root      163: }
                    164: 
1.1.1.8   root      165: /*
                    166:  * The three file_operations structs are not static because they
                    167:  * are also used in linux/fs/fifo.c to do operations on fifo's.
                    168:  */
                    169: struct file_operations read_pipe_fops = {
1.1.1.6   root      170:        pipe_lseek,
                    171:        pipe_read,
                    172:        bad_pipe_rw,
                    173:        pipe_readdir,
1.1.1.9 ! root      174:        pipe_select,
1.1.1.6   root      175:        pipe_ioctl,
                    176:        NULL,           /* no special open code */
                    177:        pipe_read_release
                    178: };
                    179: 
1.1.1.8   root      180: struct file_operations write_pipe_fops = {
1.1.1.6   root      181:        pipe_lseek,
                    182:        bad_pipe_rw,
                    183:        pipe_write,
                    184:        pipe_readdir,
1.1.1.9 ! root      185:        pipe_select,
1.1.1.6   root      186:        pipe_ioctl,
                    187:        NULL,           /* no special open code */
                    188:        pipe_write_release
                    189: };
                    190: 
1.1.1.8   root      191: struct file_operations rdwr_pipe_fops = {
                    192:        pipe_lseek,
                    193:        pipe_read,
                    194:        pipe_write,
                    195:        pipe_readdir,
1.1.1.9 ! root      196:        pipe_select,
1.1.1.8   root      197:        pipe_ioctl,
                    198:        NULL,           /* no special open code */
                    199:        pipe_rdwr_release
                    200: };
                    201: 
1.1       root      202: int sys_pipe(unsigned long * fildes)
                    203: {
1.1.1.4   root      204:        struct inode * inode;
1.1       root      205:        struct file * f[2];
                    206:        int fd[2];
                    207:        int i,j;
                    208: 
1.1.1.7   root      209:        verify_area(fildes,8);
1.1.1.9 ! root      210:        for(j=0 ; j<2 ; j++)
        !           211:                if (!(f[j] = get_empty_filp()))
        !           212:                        break;
1.1       root      213:        if (j==1)
1.1.1.9 ! root      214:                f[0]->f_count--;
1.1       root      215:        if (j<2)
1.1.1.9 ! root      216:                return -ENFILE;
1.1       root      217:        j=0;
                    218:        for(i=0;j<2 && i<NR_OPEN;i++)
                    219:                if (!current->filp[i]) {
                    220:                        current->filp[ fd[j]=i ] = f[j];
                    221:                        j++;
                    222:                }
                    223:        if (j==1)
                    224:                current->filp[fd[0]]=NULL;
                    225:        if (j<2) {
1.1.1.9 ! root      226:                f[0]->f_count--;
        !           227:                f[1]->f_count--;
        !           228:                return -EMFILE;
1.1       root      229:        }
                    230:        if (!(inode=get_pipe_inode())) {
1.1.1.9 ! root      231:                current->filp[fd[0]] = NULL;
        !           232:                current->filp[fd[1]] = NULL;
        !           233:                f[0]->f_count--;
        !           234:                f[1]->f_count--;
        !           235:                return -ENFILE;
1.1       root      236:        }
                    237:        f[0]->f_inode = f[1]->f_inode = inode;
                    238:        f[0]->f_pos = f[1]->f_pos = 0;
1.1.1.7   root      239:        f[0]->f_flags = f[1]->f_flags = 0;
1.1.1.6   root      240:        f[0]->f_op = &read_pipe_fops;
1.1       root      241:        f[0]->f_mode = 1;               /* read */
1.1.1.6   root      242:        f[1]->f_op = &write_pipe_fops;
1.1       root      243:        f[1]->f_mode = 2;               /* write */
                    244:        put_fs_long(fd[0],0+fildes);
                    245:        put_fs_long(fd[1],1+fildes);
                    246:        return 0;
                    247: }

unix.superglobalmegacorp.com

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