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. bad_pipe_rw
  5. pipe_ioctl
  6. pipe_select
  7. fifo_select
  8. connect_read
  9. connect_select
  10. pipe_read_release
  11. pipe_write_release
  12. pipe_rdwr_release
  13. do_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 bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126         return -EBADF;
 127 }
 128 
 129 static int pipe_ioctl(struct inode *pino, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 130         unsigned int cmd, unsigned long arg)
 131 {
 132         int error;
 133 
 134         switch (cmd) {
 135                 case FIONREAD:
 136                         error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int));
 137                         if (!error)
 138                                 put_user(PIPE_SIZE(*pino),(int *) arg);
 139                         return error;
 140                 default:
 141                         return -EINVAL;
 142         }
 143 }
 144 
 145 static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147         switch (sel_type) {
 148                 case SEL_IN:
 149                         if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
 150                                 return 1;
 151                         select_wait(&PIPE_WAIT(*inode), wait);
 152                         return 0;
 153                 case SEL_OUT:
 154                         if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
 155                                 return 1;
 156                         select_wait(&PIPE_WAIT(*inode), wait);
 157                         return 0;
 158                 case SEL_EX:
 159                         if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 160                                 return 1;
 161                         select_wait(&inode->i_wait,wait);
 162                         return 0;
 163         }
 164         return 0;
 165 }
 166 
 167 /*
 168  * Arggh. Why does SunOS have to have different select() behaviour
 169  * for pipes and fifos? Hate-Hate-Hate. See difference in SEL_IN..
 170  */
 171 static int fifo_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 172 {
 173         switch (sel_type) {
 174                 case SEL_IN:
 175                         if (!PIPE_EMPTY(*inode))
 176                                 return 1;
 177                         select_wait(&PIPE_WAIT(*inode), wait);
 178                         return 0;
 179                 case SEL_OUT:
 180                         if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
 181                                 return 1;
 182                         select_wait(&PIPE_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  * The 'connect_xxx()' functions are needed for named pipes when
 195  * the open() code hasn't guaranteed a connection (O_NONBLOCK),
 196  * and we need to act differently until we do get a writer..
 197  */
 198 static int connect_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 199 {
 200         while (!PIPE_SIZE(*inode)) {
 201                 if (PIPE_WRITERS(*inode))
 202                         break;
 203                 if (filp->f_flags & O_NONBLOCK)
 204                         return -EAGAIN;
 205                 wake_up_interruptible(& PIPE_WAIT(*inode));
 206                 if (current->signal & ~current->blocked)
 207                         return -ERESTARTSYS;
 208                 interruptible_sleep_on(& PIPE_WAIT(*inode));
 209         }
 210         filp->f_op = &read_fifo_fops;
 211         return pipe_read(inode,filp,buf,count);
 212 }
 213 
 214 static int connect_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216         switch (sel_type) {
 217                 case SEL_IN:
 218                         if (!PIPE_EMPTY(*inode)) {
 219                                 filp->f_op = &read_fifo_fops;
 220                                 return 1;
 221                         }
 222                         select_wait(&PIPE_WAIT(*inode), wait);
 223                         return 0;
 224                 case SEL_OUT:
 225                         if (!PIPE_FULL(*inode))
 226                                 return 1;
 227                         select_wait(&PIPE_WAIT(*inode), wait);
 228                         return 0;
 229                 case SEL_EX:
 230                         if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
 231                                 return 1;
 232                         select_wait(&inode->i_wait,wait);
 233                         return 0;
 234         }
 235         return 0;
 236 }
 237 
 238 /*
 239  * Ok, these three routines NOW keep track of readers/writers,
 240  * Linus previously did it with inode->i_count checking.
 241  */
 242 static void pipe_read_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 243 {
 244         PIPE_READERS(*inode)--;
 245         wake_up_interruptible(&PIPE_WAIT(*inode));
 246 }
 247 
 248 static void pipe_write_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 249 {
 250         PIPE_WRITERS(*inode)--;
 251         wake_up_interruptible(&PIPE_WAIT(*inode));
 252 }
 253 
 254 static void pipe_rdwr_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 255 {
 256         PIPE_READERS(*inode)--;
 257         PIPE_WRITERS(*inode)--;
 258         wake_up_interruptible(&PIPE_WAIT(*inode));
 259 }
 260 
 261 /*
 262  * The file_operations structs are not static because they
 263  * are also used in linux/fs/fifo.c to do operations on fifo's.
 264  */
 265 struct file_operations connecting_fifo_fops = {
 266         pipe_lseek,
 267         connect_read,
 268         bad_pipe_rw,
 269         NULL,           /* no readdir */
 270         connect_select,
 271         pipe_ioctl,
 272         NULL,           /* no mmap on pipes.. surprise */
 273         NULL,           /* no special open code */
 274         pipe_read_release,
 275         NULL
 276 };
 277 
 278 struct file_operations read_fifo_fops = {
 279         pipe_lseek,
 280         pipe_read,
 281         bad_pipe_rw,
 282         NULL,           /* no readdir */
 283         fifo_select,
 284         pipe_ioctl,
 285         NULL,           /* no mmap on pipes.. surprise */
 286         NULL,           /* no special open code */
 287         pipe_read_release,
 288         NULL
 289 };
 290 
 291 struct file_operations write_fifo_fops = {
 292         pipe_lseek,
 293         bad_pipe_rw,
 294         pipe_write,
 295         NULL,           /* no readdir */
 296         fifo_select,
 297         pipe_ioctl,
 298         NULL,           /* mmap */
 299         NULL,           /* no special open code */
 300         pipe_write_release,
 301         NULL
 302 };
 303 
 304 struct file_operations rdwr_fifo_fops = {
 305         pipe_lseek,
 306         pipe_read,
 307         pipe_write,
 308         NULL,           /* no readdir */
 309         fifo_select,
 310         pipe_ioctl,
 311         NULL,           /* mmap */
 312         NULL,           /* no special open code */
 313         pipe_rdwr_release,
 314         NULL
 315 };
 316 
 317 struct file_operations read_pipe_fops = {
 318         pipe_lseek,
 319         pipe_read,
 320         bad_pipe_rw,
 321         NULL,           /* no readdir */
 322         pipe_select,
 323         pipe_ioctl,
 324         NULL,           /* no mmap on pipes.. surprise */
 325         NULL,           /* no special open code */
 326         pipe_read_release,
 327         NULL
 328 };
 329 
 330 struct file_operations write_pipe_fops = {
 331         pipe_lseek,
 332         bad_pipe_rw,
 333         pipe_write,
 334         NULL,           /* no readdir */
 335         pipe_select,
 336         pipe_ioctl,
 337         NULL,           /* mmap */
 338         NULL,           /* no special open code */
 339         pipe_write_release,
 340         NULL
 341 };
 342 
 343 struct file_operations rdwr_pipe_fops = {
 344         pipe_lseek,
 345         pipe_read,
 346         pipe_write,
 347         NULL,           /* no readdir */
 348         pipe_select,
 349         pipe_ioctl,
 350         NULL,           /* mmap */
 351         NULL,           /* no special open code */
 352         pipe_rdwr_release,
 353         NULL
 354 };
 355 
 356 struct inode_operations pipe_inode_operations = {
 357         &rdwr_pipe_fops,
 358         NULL,                   /* create */
 359         NULL,                   /* lookup */
 360         NULL,                   /* link */
 361         NULL,                   /* unlink */
 362         NULL,                   /* symlink */
 363         NULL,                   /* mkdir */
 364         NULL,                   /* rmdir */
 365         NULL,                   /* mknod */
 366         NULL,                   /* rename */
 367         NULL,                   /* readlink */
 368         NULL,                   /* follow_link */
 369         NULL,                   /* bmap */
 370         NULL,                   /* truncate */
 371         NULL                    /* permission */
 372 };
 373 
 374 int do_pipe(int *fd)
     /* [previous][next][first][last][top][bottom][index][help] */
 375 {
 376         struct inode * inode;
 377         struct file *f[2];
 378         int i,j;
 379 
 380         inode = get_pipe_inode();
 381         if (!inode)
 382                 return -ENFILE;
 383 
 384         for(j=0 ; j<2 ; j++)
 385                 if (!(f[j] = get_empty_filp()))
 386                         break;
 387         if (j < 2) {
 388                 iput(inode);
 389                 if (j)
 390                         f[0]->f_count--;
 391                 return -ENFILE;
 392         }
 393         j=0;
 394         for(i=0;j<2 && i<NR_OPEN && i<current->rlim[RLIMIT_NOFILE].rlim_cur;i++)
 395                 if (!current->files->fd[i]) {
 396                         current->files->fd[ fd[j]=i ] = f[j];
 397                         j++;
 398                 }
 399         if (j<2) {
 400                 iput(inode);
 401                 f[0]->f_count--;
 402                 f[1]->f_count--;
 403                 if (j)
 404                         current->files->fd[fd[0]] = NULL;
 405                 return -EMFILE;
 406         }
 407         f[0]->f_inode = f[1]->f_inode = inode;
 408         f[0]->f_pos = f[1]->f_pos = 0;
 409         f[0]->f_flags = O_RDONLY;
 410         f[0]->f_op = &read_pipe_fops;
 411         f[0]->f_mode = 1;               /* read */
 412         f[1]->f_flags = O_WRONLY;
 413         f[1]->f_op = &write_pipe_fops;
 414         f[1]->f_mode = 2;               /* write */
 415         return 0;
 416 }

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