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. fifo_select
  9. connect_read
  10. connect_select
  11. pipe_read_release
  12. pipe_write_release
  13. pipe_rdwr_release
  14. 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 
  17 /* We don't use the head/tail construction any more. Now we use the start/len*/
  18 /* contruction providing full use of PIPE_BUF (multiple of PAGE_SIZE) */
  19 /* Florian Coosmann (FGC)                                ^ current = 1       */
  20 /* Additionally, we now use locking technique. This prevents race condition  */
  21 /* in case of paging and multiple read/write on the same pipe. (FGC)         */
  22 
  23 
  24 static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26         int chars = 0, size = 0, read = 0;
  27         char *pipebuf;
  28 
  29         if (filp->f_flags & O_NONBLOCK) {
  30                 if (PIPE_LOCK(*inode))
  31                         return -EAGAIN;
  32                 if (PIPE_EMPTY(*inode))
  33                         if (PIPE_WRITERS(*inode))
  34                                 return -EAGAIN;
  35                         else
  36                                 return 0;
  37         } else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
  38                 if (PIPE_EMPTY(*inode)) {
  39                         if (!PIPE_WRITERS(*inode))
  40                                 return 0;
  41                 }
  42                 if (current->signal & ~current->blocked)
  43                         return -ERESTARTSYS;
  44                 interruptible_sleep_on(&PIPE_WAIT(*inode));
  45         }
  46         PIPE_LOCK(*inode)++;
  47         while (count>0 && (size = PIPE_SIZE(*inode))) {
  48                 chars = PIPE_MAX_RCHUNK(*inode);
  49                 if (chars > count)
  50                         chars = count;
  51                 if (chars > size)
  52                         chars = size;
  53                 read += chars;
  54                 pipebuf = PIPE_BASE(*inode)+PIPE_START(*inode);
  55                 PIPE_START(*inode) += chars;
  56                 PIPE_START(*inode) &= (PIPE_BUF-1);
  57                 PIPE_LEN(*inode) -= chars;
  58                 count -= chars;
  59                 memcpy_tofs(buf, pipebuf, chars );
  60                 buf += chars;
  61         }
  62         PIPE_LOCK(*inode)--;
  63         wake_up_interruptible(&PIPE_WAIT(*inode));
  64         if (read)
  65                 return read;
  66         if (PIPE_WRITERS(*inode))
  67                 return -EAGAIN;
  68         return 0;
  69 }
  70         
  71 static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73         int chars = 0, free = 0, written = 0;
  74         char *pipebuf;
  75 
  76         if (!PIPE_READERS(*inode)) { /* no readers */
  77                 send_sig(SIGPIPE,current,0);
  78                 return -EPIPE;
  79         }
  80 /* if count <= PIPE_BUF, we have to make it atomic */
  81         if (count <= PIPE_BUF)
  82                 free = count;
  83         else
  84                 free = 1; /* can't do it atomically, wait for any free space */
  85         while (count>0) {
  86                 while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) {
  87                         if (!PIPE_READERS(*inode)) { /* no readers */
  88                                 send_sig(SIGPIPE,current,0);
  89                                 return written? :-EPIPE;
  90                         }
  91                         if (current->signal & ~current->blocked)
  92                                 return written? :-ERESTARTSYS;
  93                         if (filp->f_flags & O_NONBLOCK)
  94                                 return written? :-EAGAIN;
  95                         interruptible_sleep_on(&PIPE_WAIT(*inode));
  96                 }
  97                 PIPE_LOCK(*inode)++;
  98                 while (count>0 && (free = PIPE_FREE(*inode))) {
  99                         chars = PIPE_MAX_WCHUNK(*inode);
 100                         if (chars > count)
 101                                 chars = count;
 102                         if (chars > free)
 103                                 chars = free;
 104                         pipebuf = PIPE_BASE(*inode)+PIPE_END(*inode);
 105                         written += chars;
 106                         PIPE_LEN(*inode) += chars;
 107                         count -= chars;
 108                         memcpy_fromfs(pipebuf, buf, chars );
 109                         buf += chars;
 110                 }
 111                 PIPE_LOCK(*inode)--;
 112                 wake_up_interruptible(&PIPE_WAIT(*inode));
 113                 free = 1;
 114         }
 115         return written;
 116 }
 117 
 118 static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120         return -ESPIPE;
 121 }
 122 
 123 static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125         return -ENOTDIR;
 126 }
 127 
 128 static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130         return -EBADF;
 131 }
 132 
 133 static int pipe_ioctl(struct inode *pino, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 134         unsigned int cmd, unsigned long arg)
 135 {
 136         int error;
 137 
 138         switch (cmd) {
 139                 case FIONREAD:
 140                         error = verify_area(VERIFY_WRITE, (void *) arg,4);
 141                         if (!error)
 142                                 put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
 143                         return error;
 144                 default:
 145                         return -EINVAL;
 146         }
 147 }
 148 
 149 static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 150 {
 151         switch (sel_type) {
 152                 case SEL_IN:
 153                         if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
 154                                 return 1;
 155                         select_wait(&PIPE_WAIT(*inode), wait);
 156                         return 0;
 157                 case SEL_OUT:
 158                         if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
 159                                 return 1;
 160                         select_wait(&PIPE_WAIT(*inode), wait);
 161                         return 0;
 162                 case SEL_EX:
 163                         if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 164                                 return 1;
 165                         select_wait(&inode->i_wait,wait);
 166                         return 0;
 167         }
 168         return 0;
 169 }
 170 
 171 /*
 172  * Arggh. Why does SunOS have to have different select() behaviour
 173  * for pipes and fifos? Hate-Hate-Hate. See difference in SEL_IN..
 174  */
 175 static int fifo_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177         switch (sel_type) {
 178                 case SEL_IN:
 179                         if (!PIPE_EMPTY(*inode))
 180                                 return 1;
 181                         select_wait(&PIPE_WAIT(*inode), wait);
 182                         return 0;
 183                 case SEL_OUT:
 184                         if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
 185                                 return 1;
 186                         select_wait(&PIPE_WAIT(*inode), wait);
 187                         return 0;
 188                 case SEL_EX:
 189                         if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 190                                 return 1;
 191                         select_wait(&inode->i_wait,wait);
 192                         return 0;
 193         }
 194         return 0;
 195 }
 196 
 197 /*
 198  * The 'connect_xxx()' functions are needed for named pipes when
 199  * the open() code hasn't guaranteed a connection (O_NONBLOCK),
 200  * and we need to act differently until we do get a writer..
 201  */
 202 static int connect_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204         while (!PIPE_SIZE(*inode)) {
 205                 if (PIPE_WRITERS(*inode))
 206                         break;
 207                 if (filp->f_flags & O_NONBLOCK)
 208                         return -EAGAIN;
 209                 wake_up_interruptible(& PIPE_WAIT(*inode));
 210                 if (current->signal & ~current->blocked)
 211                         return -ERESTARTSYS;
 212                 interruptible_sleep_on(& PIPE_WAIT(*inode));
 213         }
 214         filp->f_op = &read_fifo_fops;
 215         return pipe_read(inode,filp,buf,count);
 216 }
 217 
 218 static int connect_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220         switch (sel_type) {
 221                 case SEL_IN:
 222                         if (!PIPE_EMPTY(*inode)) {
 223                                 filp->f_op = &read_fifo_fops;
 224                                 return 1;
 225                         }
 226                         select_wait(&PIPE_WAIT(*inode), wait);
 227                         return 0;
 228                 case SEL_OUT:
 229                         if (!PIPE_FULL(*inode))
 230                                 return 1;
 231                         select_wait(&PIPE_WAIT(*inode), wait);
 232                         return 0;
 233                 case SEL_EX:
 234                         if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 235                                 return 1;
 236                         select_wait(&inode->i_wait,wait);
 237                         return 0;
 238         }
 239         return 0;
 240 }
 241 
 242 /*
 243  * Ok, these three routines NOW keep track of readers/writers,
 244  * Linus previously did it with inode->i_count checking.
 245  */
 246 static void pipe_read_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 247 {
 248         PIPE_READERS(*inode)--;
 249         wake_up_interruptible(&PIPE_WAIT(*inode));
 250 }
 251 
 252 static void pipe_write_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 253 {
 254         PIPE_WRITERS(*inode)--;
 255         wake_up_interruptible(&PIPE_WAIT(*inode));
 256 }
 257 
 258 static void pipe_rdwr_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 259 {
 260         PIPE_READERS(*inode)--;
 261         PIPE_WRITERS(*inode)--;
 262         wake_up_interruptible(&PIPE_WAIT(*inode));
 263 }
 264 
 265 /*
 266  * The file_operations structs are not static because they
 267  * are also used in linux/fs/fifo.c to do operations on fifo's.
 268  */
 269 struct file_operations connecting_fifo_fops = {
 270         pipe_lseek,
 271         connect_read,
 272         bad_pipe_rw,
 273         pipe_readdir,
 274         connect_select,
 275         pipe_ioctl,
 276         NULL,           /* no mmap on pipes.. surprise */
 277         NULL,           /* no special open code */
 278         pipe_read_release,
 279         NULL
 280 };
 281 
 282 struct file_operations read_fifo_fops = {
 283         pipe_lseek,
 284         pipe_read,
 285         bad_pipe_rw,
 286         pipe_readdir,
 287         fifo_select,
 288         pipe_ioctl,
 289         NULL,           /* no mmap on pipes.. surprise */
 290         NULL,           /* no special open code */
 291         pipe_read_release,
 292         NULL
 293 };
 294 
 295 struct file_operations write_fifo_fops = {
 296         pipe_lseek,
 297         bad_pipe_rw,
 298         pipe_write,
 299         pipe_readdir,
 300         fifo_select,
 301         pipe_ioctl,
 302         NULL,           /* mmap */
 303         NULL,           /* no special open code */
 304         pipe_write_release,
 305         NULL
 306 };
 307 
 308 struct file_operations rdwr_fifo_fops = {
 309         pipe_lseek,
 310         pipe_read,
 311         pipe_write,
 312         pipe_readdir,
 313         fifo_select,
 314         pipe_ioctl,
 315         NULL,           /* mmap */
 316         NULL,           /* no special open code */
 317         pipe_rdwr_release,
 318         NULL
 319 };
 320 
 321 struct file_operations read_pipe_fops = {
 322         pipe_lseek,
 323         pipe_read,
 324         bad_pipe_rw,
 325         pipe_readdir,
 326         pipe_select,
 327         pipe_ioctl,
 328         NULL,           /* no mmap on pipes.. surprise */
 329         NULL,           /* no special open code */
 330         pipe_read_release,
 331         NULL
 332 };
 333 
 334 struct file_operations write_pipe_fops = {
 335         pipe_lseek,
 336         bad_pipe_rw,
 337         pipe_write,
 338         pipe_readdir,
 339         pipe_select,
 340         pipe_ioctl,
 341         NULL,           /* mmap */
 342         NULL,           /* no special open code */
 343         pipe_write_release,
 344         NULL
 345 };
 346 
 347 struct file_operations rdwr_pipe_fops = {
 348         pipe_lseek,
 349         pipe_read,
 350         pipe_write,
 351         pipe_readdir,
 352         pipe_select,
 353         pipe_ioctl,
 354         NULL,           /* mmap */
 355         NULL,           /* no special open code */
 356         pipe_rdwr_release,
 357         NULL
 358 };
 359 
 360 struct inode_operations pipe_inode_operations = {
 361         &rdwr_pipe_fops,
 362         NULL,                   /* create */
 363         NULL,                   /* lookup */
 364         NULL,                   /* link */
 365         NULL,                   /* unlink */
 366         NULL,                   /* symlink */
 367         NULL,                   /* mkdir */
 368         NULL,                   /* rmdir */
 369         NULL,                   /* mknod */
 370         NULL,                   /* rename */
 371         NULL,                   /* readlink */
 372         NULL,                   /* follow_link */
 373         NULL,                   /* bmap */
 374         NULL,                   /* truncate */
 375         NULL                    /* permission */
 376 };
 377 
 378 asmlinkage int sys_pipe(unsigned long * fildes)
     /* [previous][next][first][last][top][bottom][index][help] */
 379 {
 380         struct inode * inode;
 381         struct file * f[2];
 382         int fd[2];
 383         int i,j;
 384 
 385         j = verify_area(VERIFY_WRITE,fildes,8);
 386         if (j)
 387                 return j;
 388         for(j=0 ; j<2 ; j++)
 389                 if (!(f[j] = get_empty_filp()))
 390                         break;
 391         if (j==1)
 392                 f[0]->f_count--;
 393         if (j<2)
 394                 return -ENFILE;
 395         j=0;
 396         for(i=0;j<2 && i<NR_OPEN;i++)
 397                 if (!current->files->fd[i]) {
 398                         current->files->fd[ fd[j]=i ] = f[j];
 399                         j++;
 400                 }
 401         if (j==1)
 402                 current->files->fd[fd[0]]=NULL;
 403         if (j<2) {
 404                 f[0]->f_count--;
 405                 f[1]->f_count--;
 406                 return -EMFILE;
 407         }
 408         if (!(inode=get_pipe_inode())) {
 409                 current->files->fd[fd[0]] = NULL;
 410                 current->files->fd[fd[1]] = NULL;
 411                 f[0]->f_count--;
 412                 f[1]->f_count--;
 413                 return -ENFILE;
 414         }
 415         f[0]->f_inode = f[1]->f_inode = inode;
 416         f[0]->f_pos = f[1]->f_pos = 0;
 417         f[0]->f_flags = O_RDONLY;
 418         f[0]->f_op = &read_pipe_fops;
 419         f[0]->f_mode = 1;               /* read */
 420         f[1]->f_flags = O_WRONLY;
 421         f[1]->f_op = &write_pipe_fops;
 422         f[1]->f_mode = 2;               /* write */
 423         put_fs_long(fd[0],0+fildes);
 424         put_fs_long(fd[1],1+fildes);
 425         return 0;
 426 }

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