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. connect_read
  9. connect_select
  10. pipe_read_release
  11. pipe_write_release
  12. pipe_rdwr_release
  13. 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         if (read)
  44                 return read;
  45         if (PIPE_WRITERS(*inode))
  46                 return -EAGAIN;
  47         return 0;
  48 }
  49         
  50 static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52         int chars, size, written = 0;
  53 
  54         if (!PIPE_READERS(*inode)) { /* no readers */
  55                 send_sig(SIGPIPE,current,0);
  56                 return -EPIPE;
  57         }
  58 /* if count < PAGE_SIZE, we have to make it atomic */
  59         if (count < PAGE_SIZE)
  60                 size = PAGE_SIZE-count;
  61         else
  62                 size = PAGE_SIZE-1;
  63         while (count>0) {
  64                 while (PIPE_SIZE(*inode) >= size) {
  65                         if (!PIPE_READERS(*inode)) { /* no readers */
  66                                 send_sig(SIGPIPE,current,0);
  67                                 return written?written:-EPIPE;
  68                         }
  69                         if (current->signal & ~current->blocked)
  70                                 return written?written:-ERESTARTSYS;
  71                         if (filp->f_flags & O_NONBLOCK)
  72                                 return written?written:-EAGAIN;
  73                         else
  74                                 interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
  75                 }
  76                 while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
  77                         chars = PAGE_SIZE-PIPE_HEAD(*inode);
  78                         if (chars > count)
  79                                 chars = count;
  80                         if (chars > size)
  81                                 chars = size;
  82                         memcpy_fromfs(PIPE_BASE(*inode)+PIPE_HEAD(*inode), buf, chars );
  83                         written += chars;
  84                         PIPE_HEAD(*inode) += chars;
  85                         PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
  86                         count -= chars;
  87                         buf += chars;
  88                 }
  89                 wake_up(& PIPE_READ_WAIT(*inode));
  90                 size = PAGE_SIZE-1;
  91         }
  92         return written;
  93 }
  94 
  95 static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97         return -ESPIPE;
  98 }
  99 
 100 static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         return -ENOTDIR;
 103 }
 104 
 105 static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107         return -EBADF;
 108 }
 109 
 110 static int pipe_ioctl(struct inode *pino, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 111         unsigned int cmd, unsigned long arg)
 112 {
 113         int error;
 114 
 115         switch (cmd) {
 116                 case FIONREAD:
 117                         error = verify_area(VERIFY_WRITE, (void *) arg,4);
 118                         if (!error)
 119                                 put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
 120                         return error;
 121                 default:
 122                         return -EINVAL;
 123         }
 124 }
 125 
 126 static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         switch (sel_type) {
 129                 case SEL_IN:
 130                         if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
 131                                 return 1;
 132                         select_wait(&PIPE_READ_WAIT(*inode), wait);
 133                         return 0;
 134                 case SEL_OUT:
 135                         if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
 136                                 return 1;
 137                         select_wait(&PIPE_WRITE_WAIT(*inode), wait);
 138                         return 0;
 139                 case SEL_EX:
 140                         if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 141                                 return 1;
 142                         select_wait(&inode->i_wait,wait);
 143                         return 0;
 144         }
 145         return 0;
 146 }
 147 
 148 /*
 149  * The 'connect_xxx()' functions are needed for named pipes when
 150  * the open() code hasn't guaranteed a connection (O_NONBLOCK),
 151  * and we need to act differently until we do get a writer..
 152  */
 153 static int connect_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155         while (!PIPE_SIZE(*inode)) {
 156                 if (PIPE_WRITERS(*inode))
 157                         break;
 158                 if (filp->f_flags & O_NONBLOCK)
 159                         return -EAGAIN;
 160                 wake_up(& PIPE_WRITE_WAIT(*inode));
 161                 if (current->signal & ~current->blocked)
 162                         return -ERESTARTSYS;
 163                 interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
 164         }
 165         filp->f_op = &read_pipe_fops;
 166         return pipe_read(inode,filp,buf,count);
 167 }
 168 
 169 static int connect_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171         switch (sel_type) {
 172                 case SEL_IN:
 173                         if (!PIPE_EMPTY(*inode)) {
 174                                 filp->f_op = &read_pipe_fops;
 175                                 return 1;
 176                         }
 177                         select_wait(&PIPE_READ_WAIT(*inode), wait);
 178                         return 0;
 179                 case SEL_OUT:
 180                         if (!PIPE_FULL(*inode))
 181                                 return 1;
 182                         select_wait(&PIPE_WRITE_WAIT(*inode), wait);
 183                         return 0;
 184                 case SEL_EX:
 185                         if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 186                                 return 1;
 187                         select_wait(&inode->i_wait,wait);
 188                         return 0;
 189         }
 190         return 0;
 191 }
 192 
 193 /*
 194  * Ok, these three routines NOW keep track of readers/writers,
 195  * Linus previously did it with inode->i_count checking.
 196  */
 197 static void pipe_read_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         PIPE_READERS(*inode)--;
 200         wake_up(&PIPE_WRITE_WAIT(*inode));
 201 }
 202 
 203 static void pipe_write_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205         PIPE_WRITERS(*inode)--;
 206         wake_up(&PIPE_READ_WAIT(*inode));
 207 }
 208 
 209 static void pipe_rdwr_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 210 {
 211         PIPE_READERS(*inode)--;
 212         PIPE_WRITERS(*inode)--;
 213         wake_up(&PIPE_READ_WAIT(*inode));
 214         wake_up(&PIPE_WRITE_WAIT(*inode));
 215 }
 216 
 217 /*
 218  * The file_operations structs are not static because they
 219  * are also used in linux/fs/fifo.c to do operations on fifo's.
 220  */
 221 struct file_operations connecting_pipe_fops = {
 222         pipe_lseek,
 223         connect_read,
 224         bad_pipe_rw,
 225         pipe_readdir,
 226         connect_select,
 227         pipe_ioctl,
 228         NULL,           /* no mmap on pipes.. surprise */
 229         NULL,           /* no special open code */
 230         pipe_read_release,
 231         NULL
 232 };
 233 
 234 struct file_operations read_pipe_fops = {
 235         pipe_lseek,
 236         pipe_read,
 237         bad_pipe_rw,
 238         pipe_readdir,
 239         pipe_select,
 240         pipe_ioctl,
 241         NULL,           /* no mmap on pipes.. surprise */
 242         NULL,           /* no special open code */
 243         pipe_read_release,
 244         NULL
 245 };
 246 
 247 struct file_operations write_pipe_fops = {
 248         pipe_lseek,
 249         bad_pipe_rw,
 250         pipe_write,
 251         pipe_readdir,
 252         pipe_select,
 253         pipe_ioctl,
 254         NULL,           /* mmap */
 255         NULL,           /* no special open code */
 256         pipe_write_release,
 257         NULL
 258 };
 259 
 260 struct file_operations rdwr_pipe_fops = {
 261         pipe_lseek,
 262         pipe_read,
 263         pipe_write,
 264         pipe_readdir,
 265         pipe_select,
 266         pipe_ioctl,
 267         NULL,           /* mmap */
 268         NULL,           /* no special open code */
 269         pipe_rdwr_release,
 270         NULL
 271 };
 272 
 273 struct inode_operations pipe_inode_operations = {
 274         &rdwr_pipe_fops,
 275         NULL,                   /* create */
 276         NULL,                   /* lookup */
 277         NULL,                   /* link */
 278         NULL,                   /* unlink */
 279         NULL,                   /* symlink */
 280         NULL,                   /* mkdir */
 281         NULL,                   /* rmdir */
 282         NULL,                   /* mknod */
 283         NULL,                   /* rename */
 284         NULL,                   /* readlink */
 285         NULL,                   /* follow_link */
 286         NULL,                   /* bmap */
 287         NULL,                   /* truncate */
 288         NULL                    /* permission */
 289 };
 290 
 291 asmlinkage int sys_pipe(unsigned long * fildes)
     /* [previous][next][first][last][top][bottom][index][help] */
 292 {
 293         struct inode * inode;
 294         struct file * f[2];
 295         int fd[2];
 296         int i,j;
 297 
 298         j = verify_area(VERIFY_WRITE,fildes,8);
 299         if (j)
 300                 return j;
 301         for(j=0 ; j<2 ; j++)
 302                 if (!(f[j] = get_empty_filp()))
 303                         break;
 304         if (j==1)
 305                 f[0]->f_count--;
 306         if (j<2)
 307                 return -ENFILE;
 308         j=0;
 309         for(i=0;j<2 && i<NR_OPEN;i++)
 310                 if (!current->filp[i]) {
 311                         current->filp[ fd[j]=i ] = f[j];
 312                         j++;
 313                 }
 314         if (j==1)
 315                 current->filp[fd[0]]=NULL;
 316         if (j<2) {
 317                 f[0]->f_count--;
 318                 f[1]->f_count--;
 319                 return -EMFILE;
 320         }
 321         if (!(inode=get_pipe_inode())) {
 322                 current->filp[fd[0]] = NULL;
 323                 current->filp[fd[1]] = NULL;
 324                 f[0]->f_count--;
 325                 f[1]->f_count--;
 326                 return -ENFILE;
 327         }
 328         f[0]->f_inode = f[1]->f_inode = inode;
 329         f[0]->f_pos = f[1]->f_pos = 0;
 330         f[0]->f_flags = O_RDONLY;
 331         f[0]->f_op = &read_pipe_fops;
 332         f[0]->f_mode = 1;               /* read */
 333         f[1]->f_flags = O_WRONLY;
 334         f[1]->f_op = &write_pipe_fops;
 335         f[1]->f_mode = 2;               /* write */
 336         put_fs_long(fd[0],0+fildes);
 337         put_fs_long(fd[1],1+fildes);
 338         return 0;
 339 }

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