linux-old/fs/pipe.c
<<
>>
Prefs
   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
  25static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
  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        
  72static int pipe_write(struct inode * inode, struct file * filp, const char * buf, int count)
  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
 119static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
 120{
 121        return -ESPIPE;
 122}
 123
 124static int bad_pipe_r(struct inode * inode, struct file * filp, char * buf, int count)
 125{
 126        return -EBADF;
 127}
 128
 129static int bad_pipe_w(struct inode * inode, struct file * filp, const char * buf, int count)
 130{
 131        return -EBADF;
 132}
 133
 134static int pipe_ioctl(struct inode *pino, struct file * filp,
 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, sizeof(int));
 142                        if (!error)
 143                                put_user(PIPE_SIZE(*pino),(int *) arg);
 144                        return error;
 145                default:
 146                        return -EINVAL;
 147        }
 148}
 149
 150static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
 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 */
 176static int fifo_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
 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 */
 203static int connect_read(struct inode * inode, struct file * filp, char * buf, int count)
 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
 219static int connect_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
 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
 243static void pipe_read_release(struct inode * inode, struct file * filp)
 244{
 245        PIPE_READERS(*inode)--;
 246        wake_up_interruptible(&PIPE_WAIT(*inode));
 247}
 248
 249static void pipe_write_release(struct inode * inode, struct file * filp)
 250{
 251        PIPE_WRITERS(*inode)--;
 252        wake_up_interruptible(&PIPE_WAIT(*inode));
 253}
 254
 255static void pipe_rdwr_release(struct inode * inode, struct file * filp)
 256{
 257        PIPE_READERS(*inode)--;
 258        PIPE_WRITERS(*inode)--;
 259        wake_up_interruptible(&PIPE_WAIT(*inode));
 260}
 261
 262static int pipe_read_open(struct inode * inode, struct file * filp)
 263{
 264        PIPE_READERS(*inode)++;
 265        return 0;
 266}
 267
 268static int pipe_write_open(struct inode * inode, struct file * filp)
 269{
 270        PIPE_WRITERS(*inode)++;
 271        return 0;
 272}
 273
 274static int pipe_rdwr_open(struct inode * inode, struct file * filp)
 275{
 276        PIPE_READERS(*inode)++;
 277        PIPE_WRITERS(*inode)++;
 278        return 0;
 279}
 280
 281/*
 282 * The file_operations structs are not static because they
 283 * are also used in linux/fs/fifo.c to do operations on fifo's.
 284 */
 285struct file_operations connecting_fifo_fops = {
 286        pipe_lseek,
 287        connect_read,
 288        bad_pipe_w,
 289        NULL,           /* no readdir */
 290        connect_select,
 291        pipe_ioctl,
 292        NULL,           /* no mmap on pipes.. surprise */
 293        pipe_read_open,
 294        pipe_read_release,
 295        NULL
 296};
 297
 298struct file_operations read_fifo_fops = {
 299        pipe_lseek,
 300        pipe_read,
 301        bad_pipe_w,
 302        NULL,           /* no readdir */
 303        fifo_select,
 304        pipe_ioctl,
 305        NULL,           /* no mmap on pipes.. surprise */
 306        pipe_read_open,
 307        pipe_read_release,
 308        NULL
 309};
 310
 311struct file_operations write_fifo_fops = {
 312        pipe_lseek,
 313        bad_pipe_r,
 314        pipe_write,
 315        NULL,           /* no readdir */
 316        fifo_select,
 317        pipe_ioctl,
 318        NULL,           /* mmap */
 319        pipe_write_open,
 320        pipe_write_release,
 321        NULL
 322};
 323
 324struct file_operations rdwr_fifo_fops = {
 325        pipe_lseek,
 326        pipe_read,
 327        pipe_write,
 328        NULL,           /* no readdir */
 329        fifo_select,
 330        pipe_ioctl,
 331        NULL,           /* mmap */
 332        pipe_rdwr_open,
 333        pipe_rdwr_release,
 334        NULL
 335};
 336
 337struct file_operations read_pipe_fops = {
 338        pipe_lseek,
 339        pipe_read,
 340        bad_pipe_w,
 341        NULL,           /* no readdir */
 342        pipe_select,
 343        pipe_ioctl,
 344        NULL,           /* no mmap on pipes.. surprise */
 345        pipe_read_open,
 346        pipe_read_release,
 347        NULL
 348};
 349
 350struct file_operations write_pipe_fops = {
 351        pipe_lseek,
 352        bad_pipe_r,
 353        pipe_write,
 354        NULL,           /* no readdir */
 355        pipe_select,
 356        pipe_ioctl,
 357        NULL,           /* mmap */
 358        pipe_write_open,
 359        pipe_write_release,
 360        NULL
 361};
 362
 363struct file_operations rdwr_pipe_fops = {
 364        pipe_lseek,
 365        pipe_read,
 366        pipe_write,
 367        NULL,           /* no readdir */
 368        pipe_select,
 369        pipe_ioctl,
 370        NULL,           /* mmap */
 371        pipe_rdwr_open,
 372        pipe_rdwr_release,
 373        NULL
 374};
 375
 376struct inode_operations pipe_inode_operations = {
 377        &rdwr_pipe_fops,
 378        NULL,                   /* create */
 379        NULL,                   /* lookup */
 380        NULL,                   /* link */
 381        NULL,                   /* unlink */
 382        NULL,                   /* symlink */
 383        NULL,                   /* mkdir */
 384        NULL,                   /* rmdir */
 385        NULL,                   /* mknod */
 386        NULL,                   /* rename */
 387        NULL,                   /* readlink */
 388        NULL,                   /* follow_link */
 389        NULL,                   /* bmap */
 390        NULL,                   /* truncate */
 391        NULL                    /* permission */
 392};
 393
 394int do_pipe(int *fd)
 395{
 396        struct inode * inode;
 397        struct file *f[2];
 398        int i,j;
 399
 400        inode = get_pipe_inode();
 401        if (!inode)
 402                return -ENFILE;
 403
 404        for(j=0 ; j<2 ; j++)
 405                if (!(f[j] = get_empty_filp()))
 406                        break;
 407        if (j < 2) {
 408                iput(inode);
 409                if (j)
 410                        f[0]->f_count--;
 411                return -ENFILE;
 412        }
 413        j=0;
 414        for(i=0;j<2 && i<NR_OPEN && i<current->rlim[RLIMIT_NOFILE].rlim_cur;i++)
 415                if (!current->files->fd[i]) {
 416                        current->files->fd[ fd[j]=i ] = f[j];
 417                        j++;
 418                }
 419        if (j<2) {
 420                iput(inode);
 421                f[0]->f_count--;
 422                f[1]->f_count--;
 423                if (j)
 424                        current->files->fd[fd[0]] = NULL;
 425                return -EMFILE;
 426        }
 427        f[0]->f_inode = f[1]->f_inode = inode;
 428        f[0]->f_pos = f[1]->f_pos = 0;
 429        f[0]->f_flags = O_RDONLY;
 430        f[0]->f_op = &read_pipe_fops;
 431        f[0]->f_mode = 1;               /* read */
 432        f[1]->f_flags = O_WRONLY;
 433        f[1]->f_op = &write_pipe_fops;
 434        f[1]->f_mode = 2;               /* write */
 435        return 0;
 436}
 437