[source navigation] [diff markup] [identifier search] [freetext search] [file search]

Oldlinux Cross Reference
Linux/fs/pipe.c

Version: [1.0] [0.99.11] [0.99] [0.98] [0.97] [0.96a] [0.95] [0.12] [0.11] [0.01]
Architecture: [i386]

  1 /*
  2  *  linux/fs/pipe.c
  3  *
  4  *  (C) 1991  Linus Torvalds
  5  */
  6 
  7 #include <signal.h>
  8 
  9 #include <linux/sched.h>
 10 #include <linux/mm.h>   /* for get_free_page */
 11 #include <asm/segment.h>
 12 
 13 int read_pipe(struct m_inode * inode, char * buf, int count)
 14 {
 15         int chars, size, read = 0;
 16 
 17         while (count>0) {
 18                 while (!(size=PIPE_SIZE(*inode))) {
 19                         wake_up(&inode->i_wait);
 20                         if (inode->i_count != 2) /* are there any writers? */
 21                                 return read;
 22                         sleep_on(&inode->i_wait);
 23                 }
 24                 chars = PAGE_SIZE-PIPE_TAIL(*inode);
 25                 if (chars > count)
 26                         chars = count;
 27                 if (chars > size)
 28                         chars = size;
 29                 count -= chars;
 30                 read += chars;
 31                 size = PIPE_TAIL(*inode);
 32                 PIPE_TAIL(*inode) += chars;
 33                 PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
 34                 while (chars-->0)
 35                         put_fs_byte(((char *)inode->i_size)[size++],buf++);
 36         }
 37         wake_up(&inode->i_wait);
 38         return read;
 39 }
 40         
 41 int write_pipe(struct m_inode * inode, char * buf, int count)
 42 {
 43         int chars, size, written = 0;
 44 
 45         while (count>0) {
 46                 while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
 47                         wake_up(&inode->i_wait);
 48                         if (inode->i_count != 2) { /* no readers */
 49                                 current->signal |= (1<<(SIGPIPE-1));
 50                                 return written?written:-1;
 51                         }
 52                         sleep_on(&inode->i_wait);
 53                 }
 54                 chars = PAGE_SIZE-PIPE_HEAD(*inode);
 55                 if (chars > count)
 56                         chars = count;
 57                 if (chars > size)
 58                         chars = size;
 59                 count -= chars;
 60                 written += chars;
 61                 size = PIPE_HEAD(*inode);
 62                 PIPE_HEAD(*inode) += chars;
 63                 PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
 64                 while (chars-->0)
 65                         ((char *)inode->i_size)[size++]=get_fs_byte(buf++);
 66         }
 67         wake_up(&inode->i_wait);
 68         return written;
 69 }
 70 
 71 int sys_pipe(unsigned long * fildes)
 72 {
 73         struct m_inode * inode;
 74         struct file * f[2];
 75         int fd[2];
 76         int i,j;
 77 
 78         j=0;
 79         for(i=0;j<2 && i<NR_FILE;i++)
 80                 if (!file_table[i].f_count)
 81                         (f[j++]=i+file_table)->f_count++;
 82         if (j==1)
 83                 f[0]->f_count=0;
 84         if (j<2)
 85                 return -1;
 86         j=0;
 87         for(i=0;j<2 && i<NR_OPEN;i++)
 88                 if (!current->filp[i]) {
 89                         current->filp[ fd[j]=i ] = f[j];
 90                         j++;
 91                 }
 92         if (j==1)
 93                 current->filp[fd[0]]=NULL;
 94         if (j<2) {
 95                 f[0]->f_count=f[1]->f_count=0;
 96                 return -1;
 97         }
 98         if (!(inode=get_pipe_inode())) {
 99                 current->filp[fd[0]] =
100                         current->filp[fd[1]] = NULL;
101                 f[0]->f_count = f[1]->f_count = 0;
102                 return -1;
103         }
104         f[0]->f_inode = f[1]->f_inode = inode;
105         f[0]->f_pos = f[1]->f_pos = 0;
106         f[0]->f_mode = 1;               /* read */
107         f[1]->f_mode = 2;               /* write */
108         put_fs_long(fd[0],0+fildes);
109         put_fs_long(fd[1],1+fildes);
110         return 0;
111 }
112 

[source navigation] [diff markup] [identifier search] [freetext search] [file search]

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.