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

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