示例#1
0
static struct inode * get_pipe_inode(void)
{
	extern struct inode_operations pipe_inode_operations;
	struct inode *inode = get_empty_inode();

	if (inode) {
		unsigned long page = __get_free_page(GFP_USER);

		if (!page) {
			iput(inode);
			inode = NULL;
		} else {
			PIPE_BASE(*inode) = (char *) page;
			inode->i_op = &pipe_inode_operations;
			PIPE_WAIT(*inode) = NULL;
			PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
			PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
			PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
			PIPE_LOCK(*inode) = 0;
			/*
			 * Mark the inode dirty from the very beginning,
			 * that way it will never be moved to the dirty
			 * list because "mark_inode_dirty()" will think
			 * that it already _is_ on the dirty list.
			 */
			inode->i_state = I_DIRTY;
			inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
			inode->i_uid = current->fsuid;
			inode->i_gid = current->fsgid;
			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
			inode->i_blksize = PAGE_SIZE;
		}
	}
	return inode;
}
示例#2
0
文件: inode.c 项目: lkundrak/elks
struct inode *get_pipe_inode(void)
{
    register struct inode *inode;
    extern struct inode_operations pipe_inode_operations;

    if ((inode = get_empty_inode())) {
	if (!(PIPE_BASE(*inode) = get_pipe_mem())) {
	    iput(inode);
	    return NULL;
	}
	inode->i_op = &pipe_inode_operations;
	inode->i_count = 2;	/* sum of readers/writers */
	PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
	PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
	PIPE_LOCK(*inode) = 0;
	inode->i_pipe = 1;
	inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR;
	inode->i_uid = current->euid;
	inode->i_gid = (__u8) current->egid;
	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;

#if 0
	inode->i_blksize = PAGE_SIZE;
#endif

    }
    return inode;
}
示例#3
0
struct inode* pipe_new(struct inode* inode)
{
    unsigned long page;

    page = __get_free_page(GFP_USER);
    if (!page)
        return NULL;

    inode->i_pipe = kmalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
    if (!inode->i_pipe)
        goto fail_page;

    init_waitqueue_head(PIPE_WAIT(*inode));
    PIPE_BASE(*inode) = (char*) page;
    PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
    PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
    PIPE_WAITING_WRITERS(*inode) = 0;
    PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1;
    *PIPE_FASYNC_READERS(*inode) = *PIPE_FASYNC_WRITERS(*inode) = NULL;

    return inode;
fail_page:
    free_page(page);
    return NULL;
}
示例#4
0
static struct inode * get_pipe_inode(void)
{
	struct inode *inode = new_inode(pipe_mnt->mnt_sb);

	if (!inode)
		goto fail_inode;

	if(!pipe_new(inode))
		goto fail_iput;
	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
	inode->i_fop = &rdwr_pipe_fops;

	/*
	 * Mark the inode dirty from the very beginning,
	 * that way it will never be moved to the dirty
	 * list because "mark_inode_dirty()" will think
	 * that it already _is_ on the dirty list.
	 */
	inode->i_state = I_DIRTY;
	inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
	inode->i_uid = current->fsuid;
	inode->i_gid = current->fsgid;
	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	inode->i_blksize = PAGE_SIZE;
	return inode;

fail_iput:
	iput(inode);
fail_inode:
	return NULL;
}
示例#5
0
static int pipe_rdwr_open(struct inode * inode, struct file * filp)
{
	if (filp->f_mode & FMODE_READ)
		PIPE_READERS(*inode)++;
	if (filp->f_mode & FMODE_WRITE)
		PIPE_WRITERS(*inode)++;
	return 0;
}
示例#6
0
static int pipe_rdwr_release(struct inode * inode, struct file * filp)
{
	if (filp->f_mode & FMODE_READ)
		PIPE_READERS(*inode)--;
	if (filp->f_mode & FMODE_WRITE)
		PIPE_WRITERS(*inode)--;
	return pipe_release(inode);
}
示例#7
0
static int pipe_release(struct inode * inode)
{
	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
		free_page((unsigned long) PIPE_BASE(*inode));
		PIPE_BASE(*inode) = NULL;
	}
	wake_up_interruptible(&PIPE_WAIT(*inode));
	return 0;
}
示例#8
0
static int
pipe_release(struct inode *inode, int decr, int decw)
{
	down(PIPE_SEM(*inode));
	PIPE_READERS(*inode) -= decr;
	PIPE_WRITERS(*inode) -= decw;
	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
		struct pipe_inode_info *info = inode->i_pipe;
		inode->i_pipe = NULL;
		free_page((unsigned long) info->base);
		kfree(info);
	} else {
		wake_up_interruptible(PIPE_WAIT(*inode));
	}
	up(PIPE_SEM(*inode));

	return 0;
}
示例#9
0
static int
pipe_read_open(struct inode *inode, struct file *filp)
{
    /* We could have perhaps used atomic_t, but this and friends
       below are the only places.  So it doesn't seem worthwhile.  */
    down(PIPE_SEM(*inode));
    PIPE_READERS(*inode)++;
    up(PIPE_SEM(*inode));

    return 0;
}
示例#10
0
void init_fifo(struct inode * inode)
{
	inode->i_op = &fifo_inode_operations;
	inode->i_pipe = 1;
	PIPE_LOCK(*inode) = 0;
	PIPE_BASE(*inode) = NULL;
	PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
	PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
	PIPE_WAIT(*inode) = NULL;
	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
}
示例#11
0
文件: pipe.c 项目: d33tah/whitix
int PipeClose(struct File* file)
{
	struct PipeInfo* info = (struct PipeInfo*)(file->vNode->extraInfo);

	/* TODO: Free info if there are no readers and no writers. */
	if (file->vNode->mode & VFS_ATTR_READ)
		PIPE_READERS(file)--;
	
	if (file->vNode->mode & VFS_ATTR_WRITE)
		PIPE_WRITERS(file)--;
		
	if (!PIPE_READERS(file) && !PIPE_WRITERS(file))
	{
		/* Remove the pipe. FIXME: Finish. */
		MemFree(info->base);
		MemFree(info);
	}
	
	return 0;
}
示例#12
0
static ssize_t
pipe_write(struct file *filp, const char __user *buf,
           size_t count, loff_t *ppos)
{
    struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
    return pipe_writev(filp, &iov, 1, ppos);
}

static ssize_t
bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
    return -EBADF;
}

static ssize_t
bad_pipe_w(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
{
    return -EBADF;
}

static int
pipe_ioctl(struct inode *pino, struct file *filp,
           unsigned int cmd, unsigned long arg)
{
    switch (cmd) {
    case FIONREAD:
        return put_user(PIPE_LEN(*pino), (int __user *)arg);
    default:
        return -EINVAL;
    }
}

/* No kernel lock held - fine */
static unsigned int
pipe_poll(struct file *filp, poll_table *wait)
{
    unsigned int mask;
    struct inode *inode = filp->f_dentry->d_inode;

    poll_wait(filp, PIPE_WAIT(*inode), wait);

    /* Reading only -- no need for acquiring the semaphore.  */
    mask = POLLIN | POLLRDNORM;
    if (PIPE_EMPTY(*inode))
        mask = POLLOUT | POLLWRNORM;
    if (!PIPE_WRITERS(*inode) && filp->f_version != PIPE_WCOUNTER(*inode))
        mask |= POLLHUP;
    if (!PIPE_READERS(*inode))
        mask |= POLLERR;

    return mask;
}
示例#13
0
/*
 * Argh!  Why does SunOS have to have different select() behaviour
 * for pipes and FIFOs?  Hate, hate, hate!  SunOS lacks POLLHUP.
 */
static unsigned int fifo_poll(struct file * filp, poll_table * wait)
{
	unsigned int mask;
	struct inode * inode = filp->f_dentry->d_inode;

	poll_wait(filp, &PIPE_WAIT(*inode), wait);
	mask = POLLIN | POLLRDNORM;
	if (PIPE_EMPTY(*inode))
		mask = POLLOUT | POLLWRNORM;
	if (!PIPE_READERS(*inode))
		mask |= POLLERR;
	return mask;
}
示例#14
0
static int
pipe_read_open(struct inode *inode, struct file *filp)
{
	int ret = -ENOENT;

	down(PIPE_SEM(*inode));
	if (inode->i_pipe) {
		ret = 0;
		PIPE_READERS(*inode)++;
	}
	up(PIPE_SEM(*inode));

	return ret;
}
示例#15
0
static int
pipe_rdwr_open(struct inode *inode, struct file *filp)
{
	int ret = -ENOENT;

	down(PIPE_SEM(*inode));
	if (inode->i_pipe) {
		ret = 0;
		if (filp->f_mode & FMODE_READ)
			PIPE_READERS(*inode)++;
		if (filp->f_mode & FMODE_WRITE)
			PIPE_WRITERS(*inode)++;
	}
	up(PIPE_SEM(*inode));

	return ret;
}
示例#16
0
文件: inode.c 项目: binsys/doc-linux
void minix_read_inode(struct inode * inode)
{
	struct buffer_head * bh;
	struct minix_inode * raw_inode;
	int block;

	block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
		(inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
	if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE)))
		panic("unable to read i-node block");
	raw_inode = ((struct minix_inode *) bh->b_data) +
		(inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
	inode->i_mode = raw_inode->i_mode;
	inode->i_uid = raw_inode->i_uid;
	inode->i_gid = raw_inode->i_gid;
	inode->i_nlink = raw_inode->i_nlinks;
	inode->i_size = raw_inode->i_size;
	inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
	inode->i_blocks = inode->i_blksize = 0;
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
		inode->i_rdev = raw_inode->i_zone[0];
	else for (block = 0; block < 9; block++)
		inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
	brelse(bh);
	inode->i_op = NULL;
	if (S_ISREG(inode->i_mode))
		inode->i_op = &minix_file_inode_operations;
	else if (S_ISDIR(inode->i_mode))
		inode->i_op = &minix_dir_inode_operations;
	else if (S_ISLNK(inode->i_mode))
		inode->i_op = &minix_symlink_inode_operations;
	else if (S_ISCHR(inode->i_mode))
		inode->i_op = &minix_chrdev_inode_operations;
	else if (S_ISBLK(inode->i_mode))
		inode->i_op = &minix_blkdev_inode_operations;
	else if (S_ISFIFO(inode->i_mode)) {
		inode->i_op = &minix_fifo_inode_operations;
		inode->i_pipe = 1;
		PIPE_BASE(*inode) = NULL;
		PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
		PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
		PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
	}
}
示例#17
0
文件: pipe.c 项目: RobbenBasten/elks
static int pipe_rdwr_open(register struct inode *inode,
			  register struct file *filp)
{
    debug("PIPE: rdwr called.\n");

    if(!PIPE_BASE(*inode)) {
	if(!(PIPE_BASE(*inode) = get_pipe_mem()))
	    return -ENOMEM;
#if 0
	/* next fields already set to zero by get_empty_inode() */
	PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
	PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
	PIPE_LOCK(*inode) = 0;
#endif
    }
    if (filp->f_mode & FMODE_READ) {
	(inode->u.pipe_i.readers)++;
	if(inode->u.pipe_i.writers > 0) {
	    if(inode->u.pipe_i.readers < 2)
		wake_up_interruptible(&(inode->u.pipe_i.wait));
	}
	else {
	    if(!(filp->f_flags & O_NONBLOCK) && (inode->i_sb))
		while(!(inode->u.pipe_i.writers))
		    interruptible_sleep_on(&(inode->u.pipe_i.wait));
	}
    }

    if (filp->f_mode & FMODE_WRITE) {
	(inode->u.pipe_i.writers)++;
	if(inode->u.pipe_i.readers > 0) {
	    if(inode->u.pipe_i.writers < 2)
		wake_up_interruptible(&(inode->u.pipe_i.wait));
	}
	else {
	    if(filp->f_flags & O_NONBLOCK)
		return -ENXIO;
	    while(!(inode->u.pipe_i.readers))
		interruptible_sleep_on(&(inode->u.pipe_i.wait));
	}
    }
    return 0;
}
示例#18
0
/* No kernel lock held - fine */
static unsigned int
pipe_poll(struct file *filp, poll_table *wait)
{
	unsigned int mask;
	struct inode *inode = filp->f_dentry->d_inode;

	poll_wait(filp, PIPE_WAIT(*inode), wait);

	/* Reading only -- no need for acquiring the semaphore.  */
	mask = POLLIN | POLLRDNORM;
	if (PIPE_EMPTY(*inode))
		mask = POLLOUT | POLLWRNORM;
	if (!PIPE_WRITERS(*inode) && filp->f_version != PIPE_WCOUNTER(*inode))
		mask |= POLLHUP;
	if (!PIPE_READERS(*inode))
		mask |= POLLERR;

	return mask;
}
示例#19
0
static int fifo_open(struct inode * inode,struct file * filp)
{
	int retval = 0;
	unsigned long page;

	switch( filp->f_mode ) {

	case 1:
	/*
	 *  O_RDONLY
	 *  POSIX.1 says that O_NONBLOCK means return with the FIFO
	 *  opened, even when there is no process writing the FIFO.
	 */
		filp->f_op = &connecting_fifo_fops;
		if (!PIPE_READERS(*inode)++)
			wake_up_interruptible(&PIPE_WAIT(*inode));
		if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
			PIPE_RD_OPENERS(*inode)++;
			while (!PIPE_WRITERS(*inode)) {
				if (current->signal & ~current->blocked) {
					retval = -ERESTARTSYS;
					break;
				}
				interruptible_sleep_on(&PIPE_WAIT(*inode));
			}
			if (!--PIPE_RD_OPENERS(*inode))
				wake_up_interruptible(&PIPE_WAIT(*inode));
		}
		while (PIPE_WR_OPENERS(*inode))
			interruptible_sleep_on(&PIPE_WAIT(*inode));
		if (PIPE_WRITERS(*inode))
			filp->f_op = &read_fifo_fops;
		if (retval && !--PIPE_READERS(*inode))
			wake_up_interruptible(&PIPE_WAIT(*inode));
		break;
	
	case 2:
	/*
	 *  O_WRONLY
	 *  POSIX.1 says that O_NONBLOCK means return -1 with
	 *  errno=ENXIO when there is no process reading the FIFO.
	 */
		if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
			retval = -ENXIO;
			break;
		}
		filp->f_op = &write_fifo_fops;
		if (!PIPE_WRITERS(*inode)++)
			wake_up_interruptible(&PIPE_WAIT(*inode));
		if (!PIPE_READERS(*inode)) {
			PIPE_WR_OPENERS(*inode)++;
			while (!PIPE_READERS(*inode)) {
				if (current->signal & ~current->blocked) {
					retval = -ERESTARTSYS;
					break;
				}
				interruptible_sleep_on(&PIPE_WAIT(*inode));
			}
			if (!--PIPE_WR_OPENERS(*inode))
				wake_up_interruptible(&PIPE_WAIT(*inode));
		}
		while (PIPE_RD_OPENERS(*inode))
			interruptible_sleep_on(&PIPE_WAIT(*inode));
		if (retval && !--PIPE_WRITERS(*inode))
			wake_up_interruptible(&PIPE_WAIT(*inode));
		break;
	
	case 3:
	/*
	 *  O_RDWR
	 *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
	 *  This implementation will NEVER block on a O_RDWR open, since
	 *  the process can at least talk to itself.
	 */
		filp->f_op = &rdwr_fifo_fops;
		if (!PIPE_READERS(*inode)++)
			wake_up_interruptible(&PIPE_WAIT(*inode));
		while (PIPE_WR_OPENERS(*inode))
			interruptible_sleep_on(&PIPE_WAIT(*inode));
		if (!PIPE_WRITERS(*inode)++)
			wake_up_interruptible(&PIPE_WAIT(*inode));
		while (PIPE_RD_OPENERS(*inode))
			interruptible_sleep_on(&PIPE_WAIT(*inode));
		break;

	default:
		retval = -EINVAL;
	}
	if (retval || PIPE_BASE(*inode))
		return retval;
	page = __get_free_page(GFP_KERNEL);
	if (PIPE_BASE(*inode)) {
		free_page(page);
		return 0;
	}
	if (!page)
		return -ENOMEM;
	PIPE_LOCK(*inode) = 0;
	PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
	PIPE_BASE(*inode) = (char *) page;
	return 0;
}
示例#20
0
static int pipe_read_release(struct inode * inode, struct file * filp)
{
	PIPE_READERS(*inode)--;
	return pipe_release(inode);
}
示例#21
0
static ssize_t
pipe_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
{
	struct inode *inode = filp->f_dentry->d_inode;
	ssize_t free, written, ret;

	/* Seeks are not allowed on pipes.  */
	ret = -ESPIPE;
	written = 0;
	if (ppos != &filp->f_pos)
		goto out_nolock;

	/* Null write succeeds.  */
	ret = 0;
	if (count == 0)
		goto out_nolock;

	ret = -ERESTARTSYS;
	if (down_interruptible(PIPE_SEM(*inode)))
		goto out_nolock;

	/* No readers yields SIGPIPE.  */
	if (!PIPE_READERS(*inode))
		goto sigpipe;

	/* If count <= PIPE_BUF, we have to make it atomic.  */
	free = (count <= PIPE_BUF ? count : 1);

	/* Wait, or check for, available space.  */
	if (filp->f_flags & O_NONBLOCK) {
		ret = -EAGAIN;
		if (PIPE_FREE(*inode) < free)
			goto out;
	} else {
		while (PIPE_FREE(*inode) < free) {
			PIPE_WAITING_WRITERS(*inode)++;
			pipe_wait(inode);
			PIPE_WAITING_WRITERS(*inode)--;
			ret = -ERESTARTSYS;
			if (signal_pending(current))
				goto out;

			if (!PIPE_READERS(*inode))
				goto sigpipe;
		}
	}

	/* Copy into available space.  */
	ret = -EFAULT;
	while (count > 0) {
		int space;
		char *pipebuf = PIPE_BASE(*inode) + PIPE_END(*inode);
		ssize_t chars = PIPE_MAX_WCHUNK(*inode);

		if ((space = PIPE_FREE(*inode)) != 0) {
			if (chars > count)
				chars = count;
			if (chars > space)
				chars = space;

			if (copy_from_user(pipebuf, buf, chars))
				goto out;

			written += chars;
			PIPE_LEN(*inode) += chars;
			count -= chars;
			buf += chars;
			space = PIPE_FREE(*inode);
			continue;
		}

		ret = written;
		if (filp->f_flags & O_NONBLOCK)
			break;

		do {
			/*
			 * Synchronous wake-up: it knows that this process
			 * is going to give up this CPU, so it doesn't have
			 * to do idle reschedules.
			 */
			wake_up_interruptible_sync(PIPE_WAIT(*inode));
			PIPE_WAITING_WRITERS(*inode)++;
			pipe_wait(inode);
			PIPE_WAITING_WRITERS(*inode)--;
			if (signal_pending(current))
				goto out;
			if (!PIPE_READERS(*inode))
				goto sigpipe;
		} while (!PIPE_FREE(*inode));
		ret = -EFAULT;
	}

	/* Signal readers asynchronously that there is more data.  */
	wake_up_interruptible(PIPE_WAIT(*inode));

	update_mctime(inode);

out:
	up(PIPE_SEM(*inode));
out_nolock:
	if (written)
		ret = written;
	return ret;

sigpipe:
	if (written)
		goto out;
	up(PIPE_SEM(*inode));
	send_sig(SIGPIPE, current, 0);
	return -EPIPE;
}
示例#22
0
static int pipe_read_open(struct inode * inode, struct file * filp)
{
	PIPE_READERS(*inode)++;
	return 0;
}
示例#23
0
static ssize_t
pipe_writev(struct file *filp, const struct iovec *_iov,
            unsigned long nr_segs, loff_t *ppos)
{
    struct inode *inode = filp->f_dentry->d_inode;
    ssize_t ret;
    size_t min;
    int do_wakeup;
    struct iovec *iov = (struct iovec *)_iov;
    size_t total_len;

    total_len = iov_length(iov, nr_segs);
    /* Null write succeeds. */
    if (unlikely(total_len == 0))
        return 0;

    do_wakeup = 0;
    ret = 0;
    min = total_len;
    if (min > PIPE_BUF)
        min = 1;
    down(PIPE_SEM(*inode));
    for (;;) {
        int free;
        if (!PIPE_READERS(*inode)) {
            send_sig(SIGPIPE, current, 0);
            if (!ret) ret = -EPIPE;
            break;
        }
        free = PIPE_FREE(*inode);
        if (free >= min) {
            /* transfer data */
            ssize_t chars = PIPE_MAX_WCHUNK(*inode);
            char *pipebuf = PIPE_BASE(*inode) + PIPE_END(*inode);
            /* Always wakeup, even if the copy fails. Otherwise
             * we lock up (O_NONBLOCK-)readers that sleep due to
             * syscall merging.
             */
            do_wakeup = 1;
            if (chars > total_len)
                chars = total_len;
            if (chars > free)
                chars = free;

            if (pipe_iov_copy_from_user(pipebuf, iov, chars)) {
                if (!ret) ret = -EFAULT;
                break;
            }
            ret += chars;

            PIPE_LEN(*inode) += chars;
            total_len -= chars;
            if (!total_len)
                break;
        }
        if (PIPE_FREE(*inode) && ret) {
            /* handle cyclic data buffers */
            min = 1;
            continue;
        }
        if (filp->f_flags & O_NONBLOCK) {
            if (!ret) ret = -EAGAIN;
            break;
        }
        if (signal_pending(current)) {
            if (!ret) ret = -ERESTARTSYS;
            break;
        }
        if (do_wakeup) {
            wake_up_interruptible_sync(PIPE_WAIT(*inode));
            kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
            do_wakeup = 0;
        }
        PIPE_WAITING_WRITERS(*inode)++;
        pipe_wait(inode);
        PIPE_WAITING_WRITERS(*inode)--;
    }
    up(PIPE_SEM(*inode));
    if (do_wakeup) {
        wake_up_interruptible(PIPE_WAIT(*inode));
        kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
    }
    /*
     * Hack: we turn off atime updates for -RT kernels.
     * Who uses them on pipes anyway?
     */
#ifndef CONFIG_PREEMPT_RT
    if (ret > 0)
        inode_update_time(inode, 1);	/* mtime and ctime */
#endif
    return ret;
}
示例#24
0
static ssize_t pipe_write(struct file * filp, const char * buf,
			  size_t count, loff_t *ppos)
{
	struct inode * inode = filp->f_dentry->d_inode;
	ssize_t chars = 0, free = 0, written = 0, err=0;
	char *pipebuf;

	if (ppos != &filp->f_pos)
		return -ESPIPE;

	if (!PIPE_READERS(*inode)) { /* no readers */
		send_sig(SIGPIPE,current,0);
		return -EPIPE;
	}
	/* if count <= PIPE_BUF, we have to make it atomic */
	if (count <= PIPE_BUF)
		free = count;
	else
		free = 1; /* can't do it atomically, wait for any free space */
	up(&inode->i_sem);
	if (down_interruptible(&inode->i_atomic_write)) {
		down(&inode->i_sem);
		return -ERESTARTSYS;
	}
	while (count>0) {
		while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) {
			if (!PIPE_READERS(*inode)) { /* no readers */
				send_sig(SIGPIPE,current,0);
				err = -EPIPE;
				goto errout;
			}
			if (signal_pending(current)) {
				err = -ERESTARTSYS;
				goto errout;
			}
			if (filp->f_flags & O_NONBLOCK) {
				err = -EAGAIN;
				goto errout;
			}
			interruptible_sleep_on(&PIPE_WAIT(*inode));
		}
		PIPE_LOCK(*inode)++;
		while (count>0 && (free = PIPE_FREE(*inode))) {
			chars = PIPE_MAX_WCHUNK(*inode);
			if (chars > count)
				chars = count;
			if (chars > free)
				chars = free;
                        pipebuf = PIPE_BASE(*inode)+PIPE_END(*inode);
			written += chars;
			PIPE_LEN(*inode) += chars;
			count -= chars;
			copy_from_user(pipebuf, buf, chars );
			buf += chars;
		}
		PIPE_LOCK(*inode)--;
		wake_up_interruptible(&PIPE_WAIT(*inode));
		free = 1;
	}
	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
	mark_inode_dirty(inode);
errout:
	up(&inode->i_atomic_write);
	down(&inode->i_sem);
	return written ? written : err;
}
示例#25
0
文件: pipe.c 项目: d33tah/whitix
int PipeWrite(struct File* file,BYTE* buffer,DWORD size)
{
	DWORD free = 0, chars;
	int written = 0;
	int err = 0;
		
	/* If we've got no readers on this pipe, let userspace know. */
	if (PIPE_READERS(file) == 0)
		return -EPIPE;
		
	if (size <= PIPE_BUFFER_SIZE)
		free = size;
	else
		free = 1;
		
	while (size > 0)
	{
		while ((PIPE_FREE(file) < free || PIPE_LOCK(file)))
		{
			if (!PIPE_READERS(file) == 0)
			{
				err = -EPIPE;
				goto out;
			}
			
			if (file->flags & FILE_NONBLOCK)
			{
				goto out;
			}
			
			WAIT_ON(&PIPE_WAIT(file), PIPE_LOCK(file) == 0);
		}
		
		PIPE_LOCK(file)++;
		
		while (size > 0 && (free = PIPE_FREE(file)))
		{
			char* pipeBuf = PIPE_BUF(file) + PIPE_END(file);
			
			chars = PIPE_MAX_WCHUNK(file);
			
			if (chars > size)
				chars = size;
				
			if (chars > free)
				chars = size;
				
			/* Update counters. */
			written += chars;
			PIPE_SIZE(file) += chars;
			size -= chars;
			
			memcpy(pipeBuf, buffer, chars);
			buffer += chars;
		}
		
		PIPE_LOCK(file)--;
		WakeUp(&PIPE_WAIT(file));
		
		free = 1;
	}
	
out:
	return (written > 0) ? (written) : (err);
}
示例#26
0
文件: fifo.c 项目: dmgerman/original
static int fifo_open(struct inode *inode, struct file *filp)
{
	int ret;

	ret = -ERESTARTSYS;
	lock_kernel();
	if (down_interruptible(PIPE_SEM(*inode)))
		goto err_nolock_nocleanup;

	if (!inode->i_pipe) {
		ret = -ENOMEM;
		if(!pipe_new(inode))
			goto err_nocleanup;
	}
	filp->f_version = 0;

	switch (filp->f_mode) {
	case 1:
	/*
	 *  O_RDONLY
	 *  POSIX.1 says that O_NONBLOCK means return with the FIFO
	 *  opened, even when there is no process writing the FIFO.
	 */
		filp->f_op = &read_fifo_fops;
		PIPE_RCOUNTER(*inode)++;
		if (PIPE_READERS(*inode)++ == 0)
			wake_up_partner(inode);

		if (!PIPE_WRITERS(*inode)) {
			if ((filp->f_flags & O_NONBLOCK)) {
				/* suppress POLLHUP until we have
				 * seen a writer */
				filp->f_version = PIPE_WCOUNTER(*inode);
			} else 
			{
				wait_for_partner(inode, &PIPE_WCOUNTER(*inode));
				if(signal_pending(current))
					goto err_rd;
			}
		}
		break;
	
	case 2:
	/*
	 *  O_WRONLY
	 *  POSIX.1 says that O_NONBLOCK means return -1 with
	 *  errno=ENXIO when there is no process reading the FIFO.
	 */
		ret = -ENXIO;
		if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode))
			goto err;

		filp->f_op = &write_fifo_fops;
		PIPE_WCOUNTER(*inode)++;
		if (!PIPE_WRITERS(*inode)++)
			wake_up_partner(inode);

		if (!PIPE_READERS(*inode)) {
			wait_for_partner(inode, &PIPE_RCOUNTER(*inode));
			if (signal_pending(current))
				goto err_wr;
		}
		break;
	
	case 3:
	/*
	 *  O_RDWR
	 *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
	 *  This implementation will NEVER block on a O_RDWR open, since
	 *  the process can at least talk to itself.
	 */
		filp->f_op = &rdwr_fifo_fops;

		PIPE_READERS(*inode)++;
		PIPE_WRITERS(*inode)++;
		PIPE_RCOUNTER(*inode)++;
		PIPE_WCOUNTER(*inode)++;
		if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)
			wake_up_partner(inode);
		break;

	default:
		ret = -EINVAL;
		goto err;
	}

	/* Ok! */
	up(PIPE_SEM(*inode));
	unlock_kernel();
	return 0;

err_rd:
	if (!--PIPE_READERS(*inode))
		wake_up_interruptible(PIPE_WAIT(*inode));
	ret = -ERESTARTSYS;
	goto err;

err_wr:
	if (!--PIPE_WRITERS(*inode))
		wake_up_interruptible(PIPE_WAIT(*inode));
	ret = -ERESTARTSYS;
	goto err;

err:
	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
		struct pipe_inode_info *info = inode->i_pipe;
		inode->i_pipe = NULL;
		free_page((unsigned long)info->base);
		kfree(info);
	}

err_nocleanup:
	up(PIPE_SEM(*inode));

err_nolock_nocleanup:
	unlock_kernel();
	return ret;
}
示例#27
0
static ssize_t
pipe_writev(struct file *filp, const struct iovec *_iov,
	    unsigned long nr_segs, loff_t *ppos)
{
	struct inode *inode = filp->f_dentry->d_inode;
	struct pipe_inode_info *info;
	ssize_t ret;
	int do_wakeup;
	struct iovec *iov = (struct iovec *)_iov;
	size_t total_len;
	ssize_t chars;

	total_len = iov_length(iov, nr_segs);
	/* Null write succeeds. */
	if (unlikely(total_len == 0))
		return 0;

	do_wakeup = 0;
	ret = 0;
	down(PIPE_SEM(*inode));
	info = inode->i_pipe;

	if (!PIPE_READERS(*inode)) {
		send_sig(SIGPIPE, current, 0);
		ret = -EPIPE;
		goto out;
	}

	/* We try to merge small writes */
	chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
	if (info->nrbufs && chars != 0) {
		int lastbuf = (info->curbuf + info->nrbufs - 1) & (PIPE_BUFFERS-1);
		struct pipe_buffer *buf = info->bufs + lastbuf;
		struct pipe_buf_operations *ops = buf->ops;
		int offset = buf->offset + buf->len;
		if (ops->can_merge && offset + chars <= PAGE_SIZE) {
			void *addr = ops->map(filp, info, buf);
			int error = pipe_iov_copy_from_user(offset + addr, iov, chars);
			ops->unmap(info, buf);
			ret = error;
			do_wakeup = 1;
			if (error)
				goto out;
			buf->len += chars;
			total_len -= chars;
			ret = chars;
			if (!total_len)
				goto out;
		}
	}

	for (;;) {
		int bufs;
		if (!PIPE_READERS(*inode)) {
			send_sig(SIGPIPE, current, 0);
			if (!ret) ret = -EPIPE;
			break;
		}
		bufs = info->nrbufs;
		if (bufs < PIPE_BUFFERS) {
			int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS-1);
			struct pipe_buffer *buf = info->bufs + newbuf;
			struct page *page = info->tmp_page;
			int error;

			if (!page) {
				page = alloc_page(GFP_HIGHUSER);
				if (unlikely(!page)) {
					ret = ret ? : -ENOMEM;
					break;
				}
				info->tmp_page = page;
			}