linux-old/fs/pipe.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/pipe.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 */
   6
   7#include <linux/mm.h>
   8#include <linux/file.h>
   9#include <linux/poll.h>
  10
  11#include <asm/uaccess.h>
  12
  13/*
  14 * Define this if you want SunOS compatibility wrt braindead
  15 * select behaviour on FIFO's.
  16 */
  17#ifdef __sparc__
  18#define FIFO_SUNOS_BRAINDAMAGE
  19#else
  20#undef FIFO_SUNOS_BRAINDAMAGE
  21#endif
  22
  23/* We don't use the head/tail construction any more. Now we use the start/len*/
  24/* construction providing full use of PIPE_BUF (multiple of PAGE_SIZE) */
  25/* Florian Coosmann (FGC)                                ^ current = 1       */
  26/* Additionally, we now use locking technique. This prevents race condition  */
  27/* in case of paging and multiple read/write on the same pipe. (FGC)         */
  28/* Reads with count = 0 should always return 0. Julian Bradfield 1999-06-07. */
  29
  30static ssize_t pipe_read(struct file * filp, char * buf,
  31                         size_t count, loff_t *ppos)
  32{
  33        struct inode * inode = filp->f_dentry->d_inode;
  34        ssize_t chars = 0, size = 0, read = 0;
  35        char *pipebuf;
  36
  37
  38        if (ppos != &filp->f_pos)
  39                return -ESPIPE;
  40
  41        if ( !count ) return 0;
  42
  43        if (filp->f_flags & O_NONBLOCK) {
  44                if (PIPE_LOCK(*inode))
  45                        return -EAGAIN;
  46                if (PIPE_EMPTY(*inode)) {
  47                        if (PIPE_WRITERS(*inode))
  48                                return -EAGAIN;
  49                        else
  50                                return 0;
  51                }
  52        } else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
  53                if (PIPE_EMPTY(*inode)) {
  54                        if (!PIPE_WRITERS(*inode) || !count)
  55                                return 0;
  56                }
  57                if (signal_pending(current))
  58                        return -ERESTARTSYS;
  59                interruptible_sleep_on(&PIPE_WAIT(*inode));
  60        }
  61        PIPE_LOCK(*inode)++;
  62        while (count>0 && (size = PIPE_SIZE(*inode))) {
  63                chars = PIPE_MAX_RCHUNK(*inode);
  64                if (chars > count)
  65                        chars = count;
  66                if (chars > size)
  67                        chars = size;
  68                read += chars;
  69                pipebuf = PIPE_BASE(*inode)+PIPE_START(*inode);
  70                PIPE_START(*inode) += chars;
  71                PIPE_START(*inode) &= (PIPE_BUF-1);
  72                PIPE_LEN(*inode) -= chars;
  73                count -= chars;
  74                copy_to_user(buf, pipebuf, chars );
  75                buf += chars;
  76        }
  77        PIPE_LOCK(*inode)--;
  78        wake_up_interruptible(&PIPE_WAIT(*inode));
  79        if (read) {
  80                UPDATE_ATIME(inode);
  81                return read;
  82        }
  83        if (PIPE_WRITERS(*inode))
  84                return -EAGAIN;
  85        return 0;
  86}
  87        
  88static ssize_t pipe_write(struct file * filp, const char * buf,
  89                          size_t count, loff_t *ppos)
  90{
  91        struct inode * inode = filp->f_dentry->d_inode;
  92        ssize_t chars = 0, free = 0, written = 0, err=0;
  93        char *pipebuf;
  94
  95        if (ppos != &filp->f_pos)
  96                return -ESPIPE;
  97
  98        if (!PIPE_READERS(*inode)) { /* no readers */
  99                send_sig(SIGPIPE,current,0);
 100                return -EPIPE;
 101        }
 102        /* if count <= PIPE_BUF, we have to make it atomic */
 103        if (count <= PIPE_BUF)
 104                free = count;
 105        else
 106                free = 1; /* can't do it atomically, wait for any free space */
 107        up(&inode->i_sem);
 108        if (filp->f_flags & O_NONBLOCK) {
 109                if (down_trylock(&inode->i_atomic_write)) {
 110                        down(&inode->i_sem);
 111                        return -ERESTARTSYS;
 112                }
 113        }
 114        else {
 115                if (down_interruptible(&inode->i_atomic_write)) {
 116                        down(&inode->i_sem);
 117                        return -ERESTARTSYS;
 118                }
 119        }
 120        while (count>0) {
 121                while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) {
 122                        if (!PIPE_READERS(*inode)) { /* no readers */
 123                                send_sig(SIGPIPE,current,0);
 124                                err = -EPIPE;
 125                                goto errout;
 126                        }
 127                        if (signal_pending(current)) {
 128                                err = -ERESTARTSYS;
 129                                goto errout;
 130                        }
 131                        if (filp->f_flags & O_NONBLOCK) {
 132                                err = -EAGAIN;
 133                                goto errout;
 134                        }
 135                        interruptible_sleep_on(&PIPE_WAIT(*inode));
 136                }
 137                PIPE_LOCK(*inode)++;
 138                while (count>0 && (free = PIPE_FREE(*inode))) {
 139                        chars = PIPE_MAX_WCHUNK(*inode);
 140                        if (chars > count)
 141                                chars = count;
 142                        if (chars > free)
 143                                chars = free;
 144                        pipebuf = PIPE_BASE(*inode)+PIPE_END(*inode);
 145                        written += chars;
 146                        PIPE_LEN(*inode) += chars;
 147                        count -= chars;
 148                        copy_from_user(pipebuf, buf, chars );
 149                        buf += chars;
 150                }
 151                PIPE_LOCK(*inode)--;
 152                wake_up_interruptible(&PIPE_WAIT(*inode));
 153                free = 1;
 154        }
 155        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 156        mark_inode_dirty(inode);
 157errout:
 158        up(&inode->i_atomic_write);
 159        down(&inode->i_sem);
 160        return written ? written : err;
 161}
 162
 163static long long pipe_lseek(struct file * file, long long offset, int orig)
 164{
 165        return -ESPIPE;
 166}
 167
 168static ssize_t bad_pipe_r(struct file * filp, char * buf,
 169                          size_t count, loff_t *ppos)
 170{
 171        return -EBADF;
 172}
 173
 174static ssize_t bad_pipe_w(struct file * filp, const char * buf,
 175                          size_t count, loff_t *ppos)
 176{
 177        return -EBADF;
 178}
 179
 180static int pipe_ioctl(struct inode *pino, struct file * filp,
 181                      unsigned int cmd, unsigned long arg)
 182{
 183        switch (cmd) {
 184                case FIONREAD:
 185                        return put_user(PIPE_SIZE(*pino),(int *) arg);
 186                default:
 187                        return -EINVAL;
 188        }
 189}
 190
 191static unsigned int pipe_poll(struct file * filp, poll_table * wait)
 192{
 193        unsigned int mask;
 194        struct inode * inode = filp->f_dentry->d_inode;
 195
 196        poll_wait(filp, &PIPE_WAIT(*inode), wait);
 197        mask = POLLIN | POLLRDNORM;
 198        if (PIPE_EMPTY(*inode))
 199                mask = POLLOUT | POLLWRNORM;
 200        if (!PIPE_WRITERS(*inode))
 201                mask |= POLLHUP;
 202        if (!PIPE_READERS(*inode))
 203                mask |= POLLERR;
 204        return mask;
 205}
 206
 207#ifdef FIFO_SUNOS_BRAINDAMAGE
 208/*
 209 * Argh!  Why does SunOS have to have different select() behaviour
 210 * for pipes and FIFOs?  Hate, hate, hate!  SunOS lacks POLLHUP.
 211 */
 212static unsigned int fifo_poll(struct file * filp, poll_table * wait)
 213{
 214        unsigned int mask;
 215        struct inode * inode = filp->f_dentry->d_inode;
 216
 217        poll_wait(filp, &PIPE_WAIT(*inode), wait);
 218        mask = POLLIN | POLLRDNORM;
 219        if (PIPE_EMPTY(*inode))
 220                mask = POLLOUT | POLLWRNORM;
 221        if (!PIPE_READERS(*inode))
 222                mask |= POLLERR;
 223        return mask;
 224}
 225#else
 226
 227#define fifo_poll pipe_poll
 228
 229#endif /* FIFO_SUNOS_BRAINDAMAGE */
 230
 231/*
 232 * The 'connect_xxx()' functions are needed for named pipes when
 233 * the open() code hasn't guaranteed a connection (O_NONBLOCK),
 234 * and we need to act differently until we do get a writer..
 235 */
 236static ssize_t connect_read(struct file * filp, char * buf,
 237                            size_t count, loff_t *ppos)
 238{
 239        struct inode * inode = filp->f_dentry->d_inode;
 240        if (PIPE_EMPTY(*inode) && !PIPE_WRITERS(*inode))
 241                return 0;
 242        filp->f_op = &read_fifo_fops;
 243        return pipe_read(filp,buf,count,ppos);
 244}
 245
 246static unsigned int connect_poll(struct file * filp, poll_table * wait)
 247{
 248        struct inode * inode = filp->f_dentry->d_inode;
 249
 250        poll_wait(filp, &PIPE_WAIT(*inode), wait);
 251        if (!PIPE_EMPTY(*inode)) {
 252                filp->f_op = &read_fifo_fops;
 253                return POLLIN | POLLRDNORM;
 254        }
 255        if (PIPE_WRITERS(*inode))
 256                filp->f_op = &read_fifo_fops;
 257        return POLLOUT | POLLWRNORM;
 258}
 259
 260static int pipe_release(struct inode * inode)
 261{
 262        if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
 263                free_page((unsigned long) PIPE_BASE(*inode));
 264                PIPE_BASE(*inode) = NULL;
 265        }
 266        wake_up_interruptible(&PIPE_WAIT(*inode));
 267        return 0;
 268}
 269
 270static int pipe_read_release(struct inode * inode, struct file * filp)
 271{
 272        PIPE_READERS(*inode)--;
 273        return pipe_release(inode);
 274}
 275
 276static int pipe_write_release(struct inode * inode, struct file * filp)
 277{
 278        PIPE_WRITERS(*inode)--;
 279        return pipe_release(inode);
 280}
 281
 282static int pipe_rdwr_release(struct inode * inode, struct file * filp)
 283{
 284        if (filp->f_mode & FMODE_READ)
 285                PIPE_READERS(*inode)--;
 286        if (filp->f_mode & FMODE_WRITE)
 287                PIPE_WRITERS(*inode)--;
 288        return pipe_release(inode);
 289}
 290
 291static int pipe_read_open(struct inode * inode, struct file * filp)
 292{
 293        PIPE_READERS(*inode)++;
 294        return 0;
 295}
 296
 297static int pipe_write_open(struct inode * inode, struct file * filp)
 298{
 299        PIPE_WRITERS(*inode)++;
 300        return 0;
 301}
 302
 303static int pipe_rdwr_open(struct inode * inode, struct file * filp)
 304{
 305        if (filp->f_mode & FMODE_READ)
 306                PIPE_READERS(*inode)++;
 307        if (filp->f_mode & FMODE_WRITE)
 308                PIPE_WRITERS(*inode)++;
 309        return 0;
 310}
 311
 312/*
 313 * The file_operations structs are not static because they
 314 * are also used in linux/fs/fifo.c to do operations on FIFOs.
 315 */
 316struct file_operations connecting_fifo_fops = {
 317        pipe_lseek,
 318        connect_read,
 319        bad_pipe_w,
 320        NULL,           /* no readdir */
 321        connect_poll,
 322        pipe_ioctl,
 323        NULL,           /* no mmap on pipes.. surprise */
 324        pipe_read_open,
 325        NULL,           /* flush */
 326        pipe_read_release,
 327        NULL
 328};
 329
 330struct file_operations read_fifo_fops = {
 331        pipe_lseek,
 332        pipe_read,
 333        bad_pipe_w,
 334        NULL,           /* no readdir */
 335        fifo_poll,
 336        pipe_ioctl,
 337        NULL,           /* no mmap on pipes.. surprise */
 338        pipe_read_open,
 339        NULL,           /* flush */
 340        pipe_read_release,
 341        NULL
 342};
 343
 344struct file_operations write_fifo_fops = {
 345        pipe_lseek,
 346        bad_pipe_r,
 347        pipe_write,
 348        NULL,           /* no readdir */
 349        fifo_poll,
 350        pipe_ioctl,
 351        NULL,           /* mmap */
 352        pipe_write_open,
 353        NULL,           /* flush */
 354        pipe_write_release,
 355        NULL
 356};
 357
 358struct file_operations rdwr_fifo_fops = {
 359        pipe_lseek,
 360        pipe_read,
 361        pipe_write,
 362        NULL,           /* no readdir */
 363        fifo_poll,
 364        pipe_ioctl,
 365        NULL,           /* mmap */
 366        pipe_rdwr_open,
 367        NULL,           /* flush */
 368        pipe_rdwr_release,
 369        NULL
 370};
 371
 372struct file_operations read_pipe_fops = {
 373        pipe_lseek,
 374        pipe_read,
 375        bad_pipe_w,
 376        NULL,           /* no readdir */
 377        pipe_poll,
 378        pipe_ioctl,
 379        NULL,           /* no mmap on pipes.. surprise */
 380        pipe_read_open,
 381        NULL,           /* flush */
 382        pipe_read_release,
 383        NULL
 384};
 385
 386struct file_operations write_pipe_fops = {
 387        pipe_lseek,
 388        bad_pipe_r,
 389        pipe_write,
 390        NULL,           /* no readdir */
 391        pipe_poll,
 392        pipe_ioctl,
 393        NULL,           /* mmap */
 394        pipe_write_open,
 395        NULL,           /* flush */
 396        pipe_write_release,
 397        NULL
 398};
 399
 400struct file_operations rdwr_pipe_fops = {
 401        pipe_lseek,
 402        pipe_read,
 403        pipe_write,
 404        NULL,           /* no readdir */
 405        pipe_poll,
 406        pipe_ioctl,
 407        NULL,           /* mmap */
 408        pipe_rdwr_open,
 409        NULL,           /* flush */
 410        pipe_rdwr_release,
 411        NULL
 412};
 413
 414static struct inode * get_pipe_inode(void)
 415{
 416        extern struct inode_operations pipe_inode_operations;
 417        struct inode *inode = get_empty_inode();
 418
 419        if (inode) {
 420                unsigned long page = __get_free_page(GFP_USER);
 421
 422                if (!page) {
 423                        iput(inode);
 424                        inode = NULL;
 425                } else {
 426                        PIPE_BASE(*inode) = (char *) page;
 427                        inode->i_op = &pipe_inode_operations;
 428                        PIPE_WAIT(*inode) = NULL;
 429                        PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
 430                        PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
 431                        PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 432                        PIPE_LOCK(*inode) = 0;
 433                        /*
 434                         * Mark the inode dirty from the very beginning,
 435                         * that way it will never be moved to the dirty
 436                         * list because "mark_inode_dirty()" will think
 437                         * that it already _is_ on the dirty list.
 438                         */
 439                        inode->i_state = I_DIRTY;
 440                        inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
 441                        inode->i_uid = current->fsuid;
 442                        inode->i_gid = current->fsgid;
 443                        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 444                        inode->i_blksize = PAGE_SIZE;
 445                }
 446        }
 447        return inode;
 448}
 449
 450struct inode_operations pipe_inode_operations = {
 451        &rdwr_pipe_fops,
 452        NULL,                   /* create */
 453        NULL,                   /* lookup */
 454        NULL,                   /* link */
 455        NULL,                   /* unlink */
 456        NULL,                   /* symlink */
 457        NULL,                   /* mkdir */
 458        NULL,                   /* rmdir */
 459        NULL,                   /* mknod */
 460        NULL,                   /* rename */
 461        NULL,                   /* readlink */
 462        NULL,                   /* readpage */
 463        NULL,                   /* writepage */
 464        NULL,                   /* bmap */
 465        NULL,                   /* truncate */
 466        NULL                    /* permission */
 467};
 468
 469int do_pipe(int *fd)
 470{
 471        struct inode * inode;
 472        struct file *f1, *f2;
 473        int error;
 474        int i,j;
 475
 476        error = -ENFILE;
 477        f1 = get_empty_filp();
 478        if (!f1)
 479                goto no_files;
 480
 481        f2 = get_empty_filp();
 482        if (!f2)
 483                goto close_f1;
 484
 485        inode = get_pipe_inode();
 486        if (!inode)
 487                goto close_f12;
 488
 489        error = get_unused_fd();
 490        if (error < 0)
 491                goto close_f12_inode;
 492        i = error;
 493
 494        error = get_unused_fd();
 495        if (error < 0)
 496                goto close_f12_inode_i;
 497        j = error;
 498
 499        error = -ENOMEM;
 500        f1->f_dentry = f2->f_dentry = dget(d_alloc_root(inode, NULL));
 501        if (!f1->f_dentry)
 502                goto close_f12_inode_i_j;
 503
 504        /* read file */
 505        f1->f_pos = f2->f_pos = 0;
 506        f1->f_flags = O_RDONLY;
 507        f1->f_op = &read_pipe_fops;
 508        f1->f_mode = 1;
 509
 510        /* write file */
 511        f2->f_flags = O_WRONLY;
 512        f2->f_op = &write_pipe_fops;
 513        f2->f_mode = 2;
 514
 515        fd_install(i, f1);
 516        fd_install(j, f2);
 517        fd[0] = i;
 518        fd[1] = j;
 519        return 0;
 520
 521close_f12_inode_i_j:
 522        put_unused_fd(j);
 523close_f12_inode_i:
 524        put_unused_fd(i);
 525close_f12_inode:
 526        free_page((unsigned long) PIPE_BASE(*inode));
 527        iput(inode);
 528close_f12:
 529        put_filp(f2);
 530close_f1:
 531        put_filp(f1);
 532no_files:
 533        return error;   
 534}
 535
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.