Esempio n. 1
0
File: pipe.c Progetto: d33tah/whitix
int PipeRead(struct File* file, BYTE* buffer, DWORD count)
{
	DWORD size = 0, chars = 0;
	int read = 0;
	
	if (!count)
		return 0;
		
	if (file->flags & FILE_NONBLOCK)
	{
		if (PIPE_LOCK(file))
			return 0;
			
//		if (PIPE_EMPTY(file))
//		{
			/* return -EAGAIN? */
//			return 0;
//		}
	}else{

		while (PIPE_EMPTY(file) || PIPE_LOCK(file))
		{
			if (PIPE_EMPTY(file))
				return 0;
	
			KePrint("WAIT\n");			
//			WAIT_ON(&PIPE_WAIT(file), (PIPE_LOCK(file) == 0));
		}
	}
	
	PIPE_LOCK(file)++;
	
	while (count > 0 && (size = PIPE_SIZE(file)))
	{
		char* pipeBuf = PIPE_BUF(file) + PIPE_START(file);
		
		chars = PIPE_MAX_RCHUNK(file);
		
		if (chars > count)
			chars = count;
			
		if (chars > size)
			chars = size;
			
		read += chars;
		
		PIPE_START(file) += chars;
		PIPE_START(file) &= (PIPE_BUFFER_SIZE - 1);
		PIPE_SIZE(file) -= chars;
		count -= chars;
		memcpy(buffer, pipeBuf, chars);
		buffer+=chars;		
	}
	
	PIPE_LOCK(file)--;
	WakeUp(&PIPE_WAIT(file));
	
	return read;
}
Esempio n. 2
0
static ssize_t pipe_read(struct file * filp, char * buf,
			 size_t count, loff_t *ppos)
{
	struct inode * inode = filp->f_dentry->d_inode;
	ssize_t chars = 0, size = 0, read = 0;
        char *pipebuf;


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

	if ( !count ) return 0;

	if (filp->f_flags & O_NONBLOCK) {
		if (PIPE_LOCK(*inode))
			return -EAGAIN;
		if (PIPE_EMPTY(*inode)) {
			if (PIPE_WRITERS(*inode))
				return -EAGAIN;
			else
				return 0;
		}
	} else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
		if (PIPE_EMPTY(*inode)) {
			if (!PIPE_WRITERS(*inode) || !count)
				return 0;
		}
		if (signal_pending(current))
			return -ERESTARTSYS;
		interruptible_sleep_on(&PIPE_WAIT(*inode));
	}
	PIPE_LOCK(*inode)++;
	while (count>0 && (size = PIPE_SIZE(*inode))) {
		chars = PIPE_MAX_RCHUNK(*inode);
		if (chars > count)
			chars = count;
		if (chars > size)
			chars = size;
		read += chars;
                pipebuf = PIPE_BASE(*inode)+PIPE_START(*inode);
		PIPE_START(*inode) += chars;
		PIPE_START(*inode) &= (PIPE_BUF-1);
		PIPE_LEN(*inode) -= chars;
		count -= chars;
		copy_to_user(buf, pipebuf, chars );
		buf += chars;
	}
	PIPE_LOCK(*inode)--;
	wake_up_interruptible(&PIPE_WAIT(*inode));
	if (read) {
		UPDATE_ATIME(inode);
		return read;
	}
	if (PIPE_WRITERS(*inode))
		return -EAGAIN;
	return 0;
}
Esempio n. 3
0
int read_pipe(struct m_inode * inode, char * buf, int count)
{
	char * b=buf;

	while (PIPE_EMPTY(*inode)) {
		wake_up(&inode->i_wait);
		if (inode->i_count != 2) /* are there any writers left? */
			return 0;
		sleep_on(&inode->i_wait);
	}
	while (count>0 && !(PIPE_EMPTY(*inode))) {
		count --;
		put_fs_byte(((char *)inode->i_size)[PIPE_TAIL(*inode)],b++);
		INC_PIPE( PIPE_TAIL(*inode) );
	}
	wake_up(&inode->i_wait);
	return b-buf;
}
Esempio n. 4
0
/*
 * The 'connect_xxx()' functions are needed for named pipes when
 * the open() code hasn't guaranteed a connection (O_NONBLOCK),
 * and we need to act differently until we do get a writer..
 */
static ssize_t connect_read(struct file * filp, char * buf,
			    size_t count, loff_t *ppos)
{
	struct inode * inode = filp->f_dentry->d_inode;
	if (PIPE_EMPTY(*inode) && !PIPE_WRITERS(*inode))
		return 0;
	filp->f_op = &read_fifo_fops;
	return pipe_read(filp,buf,count,ppos);
}
Esempio n. 5
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;
}
Esempio n. 6
0
static unsigned int connect_poll(struct file * filp, poll_table * wait)
{
	struct inode * inode = filp->f_dentry->d_inode;

	poll_wait(filp, &PIPE_WAIT(*inode), wait);
	if (!PIPE_EMPTY(*inode)) {
		filp->f_op = &read_fifo_fops;
		return POLLIN | POLLRDNORM;
	}
	if (PIPE_WRITERS(*inode))
		filp->f_op = &read_fifo_fops;
	return POLLOUT | POLLWRNORM;
}
Esempio n. 7
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;
}
Esempio n. 8
0
/*
 * The check_XX functions check out a file. We know it's either
 * a pipe, a character device or a fifo (fifo's not implemented)
 */
static int check_in(select_table * wait, struct m_inode * inode)
{
	struct tty_struct * tty;

	if (tty = get_tty(inode))
		if (!EMPTY(tty->secondary))
			return 1;
		else
			add_wait(&tty->secondary->proc_list, wait);
	else if (inode->i_pipe)
		if (!PIPE_EMPTY(*inode))
			return 1;
		else
			add_wait(&inode->i_wait, wait);
	return 0;
}
Esempio n. 9
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;
}
Esempio n. 10
0
/*
 * Interface to file system read.
 */
ssize_t pipe_read(
  pipe_control_t *pipe,
  void           *buffer,
  size_t          count,
  rtems_libio_t  *iop
)
{
  int chunk, chunk1, read = 0, ret = 0;

  if (! PIPE_LOCK(pipe))
    return -EINTR;

  while (read < count) {
    while (PIPE_EMPTY(pipe)) {
      /* Not an error */
      if (pipe->Writers == 0)
        goto out_locked;

      if (LIBIO_NODELAY(iop)) {
        ret = -EAGAIN;
        goto out_locked;
      }

      /* Wait until pipe is no more empty or no writer exists */
      pipe->waitingReaders ++;
      PIPE_UNLOCK(pipe);
      if (! PIPE_READWAIT(pipe))
        ret = -EINTR;
      if (! PIPE_LOCK(pipe)) {
        /* WARN waitingReaders not restored! */
        ret = -EINTR;
        goto out_nolock;
      }
      pipe->waitingReaders --;
      if (ret != 0)
        goto out_locked;
    }

    /* Read chunk bytes */
    chunk = MIN(count - read,  pipe->Length);
    chunk1 = pipe->Size - pipe->Start;
    if (chunk > chunk1) {
      memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk1);
      memcpy(buffer + read + chunk1, pipe->Buffer, chunk - chunk1);
    }
    else
      memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk);

    pipe->Start += chunk;
    pipe->Start %= pipe->Size;
    pipe->Length -= chunk;
    /* For buffering optimization */
    if (PIPE_EMPTY(pipe))
      pipe->Start = 0;

    if (pipe->waitingWriters > 0)
      PIPE_WAKEUPWRITERS(pipe);
    read += chunk;
  }

out_locked:
  PIPE_UNLOCK(pipe);

out_nolock:
  if (read > 0)
    return read;
  return ret;
}
Esempio n. 11
0
static ssize_t
pipe_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
{
	struct inode *inode = filp->f_dentry->d_inode;
	ssize_t size, read, ret;

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

	/* Always return 0 on null read.  */
	ret = 0;
	if (count == 0)
		goto out_nolock;

	/* Get the pipe semaphore */
	ret = -ERESTARTSYS;
	if (down_interruptible(PIPE_SEM(*inode)))
		goto out_nolock;

	if (PIPE_EMPTY(*inode)) {
do_more_read:
		ret = 0;
		if (!PIPE_WRITERS(*inode))
			goto out;

		ret = -EAGAIN;
		if (filp->f_flags & O_NONBLOCK)
			goto out;

		for (;;) {
			PIPE_WAITING_READERS(*inode)++;
			pipe_wait(inode);
			PIPE_WAITING_READERS(*inode)--;
			ret = -ERESTARTSYS;
			if (signal_pending(current))
				goto out;
			ret = 0;
			if (!PIPE_EMPTY(*inode))
				break;
			if (!PIPE_WRITERS(*inode))
				goto out;
		}
	}

	/* Read what data is available.  */
	ret = -EFAULT;
	while (count > 0 && (size = PIPE_LEN(*inode))) {
		char *pipebuf = PIPE_BASE(*inode) + PIPE_START(*inode);
		ssize_t chars = PIPE_MAX_RCHUNK(*inode);

		if (chars > count)
			chars = count;
		if (chars > size)
			chars = size;

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

		read += chars;
		PIPE_START(*inode) += chars;
		PIPE_START(*inode) &= (PIPE_SIZE - 1);
		PIPE_LEN(*inode) -= chars;
		count -= chars;
		buf += chars;
	}

	/* Cache behaviour optimization */
	if (!PIPE_LEN(*inode))
		PIPE_START(*inode) = 0;

	if (count && PIPE_WAITING_WRITERS(*inode) && !(filp->f_flags & O_NONBLOCK)) {
		/*
		 * We know that we are going to sleep: signal
		 * writers synchronously that there is more
		 * room.
		 */
		wake_up_interruptible_sync(PIPE_WAIT(*inode));
		if (!PIPE_EMPTY(*inode))
			BUG();
		goto do_more_read;
	}
	/* Signal writers asynchronously that there is more room.  */
	wake_up_interruptible(PIPE_WAIT(*inode));

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

	UPDATE_ATIME(inode);
	return ret;
}