root/fs/pipe.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pipe_read
  2. pipe_write
  3. pipe_lseek
  4. pipe_readdir
  5. bad_pipe_rw
  6. pipe_ioctl
  7. pipe_select
  8. pipe_read_release
  9. pipe_write_release
  10. pipe_rdwr_release
  11. sys_pipe

   1 /*
   2  *  linux/fs/pipe.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 #include <asm/segment.h>
   8 
   9 #include <linux/sched.h>
  10 #include <linux/kernel.h>
  11 #include <linux/errno.h>
  12 #include <linux/signal.h>
  13 #include <linux/fcntl.h>
  14 #include <linux/termios.h>
  15 
  16 static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  17 {
  18         int chars, size, read = 0;
  19 
  20         if (!(filp->f_flags & O_NONBLOCK))
  21                 while (!PIPE_SIZE(*inode)) {
  22                         wake_up(& PIPE_WRITE_WAIT(*inode));
  23                         if (!PIPE_WRITERS(*inode)) /* are there any writers? */
  24                                 return 0;
  25                         if (current->signal & ~current->blocked)
  26                                 return -ERESTARTSYS;
  27                         interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
  28                 }
  29         while (count>0 && (size = PIPE_SIZE(*inode))) {
  30                 chars = PAGE_SIZE-PIPE_TAIL(*inode);
  31                 if (chars > count)
  32                         chars = count;
  33                 if (chars > size)
  34                         chars = size;
  35                 memcpy_tofs(buf, PIPE_BASE(*inode)+PIPE_TAIL(*inode), chars );
  36                 read += chars;
  37                 PIPE_TAIL(*inode) += chars;
  38                 PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
  39                 count -= chars;
  40                 buf += chars;
  41         }
  42         wake_up(& PIPE_WRITE_WAIT(*inode));
  43         return read?read:-EAGAIN;
  44 }
  45         
  46 static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48         int chars, size, written = 0;
  49 
  50         if (!PIPE_READERS(*inode)) { /* no readers */
  51                 send_sig(SIGPIPE,current,0);
  52                 return -EPIPE;
  53         }
  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;
  59         while (count>0) {
  60                 while (PIPE_SIZE(*inode) >= size) {
  61                         if (!PIPE_READERS(*inode)) { /* no readers */
  62                                 send_sig(SIGPIPE,current,0);
  63                                 return written?written:-EPIPE;
  64                         }
  65                         if (current->signal & ~current->blocked)
  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));
  71                 }
  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(PIPE_BASE(*inode)+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;
  87         }
  88         return written;
  89 }
  90 
  91 static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         return -ESPIPE;
  94 }
  95 
  96 static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98         return -ENOTDIR;
  99 }
 100 
 101 static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 102 {
 103         return -EBADF;
 104 }
 105 
 106 static int pipe_ioctl(struct inode *pino, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 119 static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 141 /*
 142  * Ok, these three routines NOW keep track of readers/writers,
 143  * Linus previously did it with inode->i_count checking.
 144  */
 145 static void pipe_read_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147         PIPE_READERS(*inode)--;
 148         wake_up(&PIPE_WRITE_WAIT(*inode));
 149 }
 150 
 151 static void pipe_write_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 152 {
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159         PIPE_READERS(*inode)--;
 160         PIPE_WRITERS(*inode)--;
 161         wake_up(&PIPE_READ_WAIT(*inode));
 162         wake_up(&PIPE_WRITE_WAIT(*inode));
 163 }
 164 
 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 = {
 170         pipe_lseek,
 171         pipe_read,
 172         bad_pipe_rw,
 173         pipe_readdir,
 174         pipe_select,
 175         pipe_ioctl,
 176         NULL,           /* no mmap on pipes.. surprise */
 177         NULL,           /* no special open code */
 178         pipe_read_release
 179 };
 180 
 181 struct file_operations write_pipe_fops = {
 182         pipe_lseek,
 183         bad_pipe_rw,
 184         pipe_write,
 185         pipe_readdir,
 186         pipe_select,
 187         pipe_ioctl,
 188         NULL,           /* mmap */
 189         NULL,           /* no special open code */
 190         pipe_write_release
 191 };
 192 
 193 struct file_operations rdwr_pipe_fops = {
 194         pipe_lseek,
 195         pipe_read,
 196         pipe_write,
 197         pipe_readdir,
 198         pipe_select,
 199         pipe_ioctl,
 200         NULL,           /* mmap */
 201         NULL,           /* no special open code */
 202         pipe_rdwr_release
 203 };
 204 
 205 int sys_pipe(unsigned long * fildes)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207         struct inode * inode;
 208         struct file * f[2];
 209         int fd[2];
 210         int i,j;
 211 
 212         verify_area(fildes,8);
 213         for(j=0 ; j<2 ; j++)
 214                 if (!(f[j] = get_empty_filp()))
 215                         break;
 216         if (j==1)
 217                 f[0]->f_count--;
 218         if (j<2)
 219                 return -ENFILE;
 220         j=0;
 221         for(i=0;j<2 && i<NR_OPEN;i++)
 222                 if (!current->filp[i]) {
 223                         current->filp[ fd[j]=i ] = f[j];
 224                         j++;
 225                 }
 226         if (j==1)
 227                 current->filp[fd[0]]=NULL;
 228         if (j<2) {
 229                 f[0]->f_count--;
 230                 f[1]->f_count--;
 231                 return -EMFILE;
 232         }
 233         if (!(inode=get_pipe_inode())) {
 234                 current->filp[fd[0]] = NULL;
 235                 current->filp[fd[1]] = NULL;
 236                 f[0]->f_count--;
 237                 f[1]->f_count--;
 238                 return -ENFILE;
 239         }
 240         f[0]->f_inode = f[1]->f_inode = inode;
 241         f[0]->f_pos = f[1]->f_pos = 0;
 242         f[0]->f_flags = f[1]->f_flags = 0;
 243         f[0]->f_op = &read_pipe_fops;
 244         f[0]->f_mode = 1;               /* read */
 245         f[1]->f_op = &write_pipe_fops;
 246         f[1]->f_mode = 2;               /* write */
 247         put_fs_long(fd[0],0+fildes);
 248         put_fs_long(fd[1],1+fildes);
 249         return 0;
 250 }

/* [previous][next][first][last][top][bottom][index][help] */