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

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

unix.superglobalmegacorp.com

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