Exemple #1
0
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;
}
Exemple #2
0
Fichier : pipe.c Projet : AmosZ/OS
int write_pipe(struct m_inode * inode, char * buf, int count)
{
	int chars, size, written = 0;

	while (count>0) {
		while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
			wake_up(&inode->i_wait);
			if (inode->i_count != 2) { /* no readers */
				current->signal |= (1<<(SIGPIPE-1));
				return written?written:-1;
			}
			sleep_on(&inode->i_wait);
		}
		chars = PAGE_SIZE-PIPE_HEAD(*inode);
		if (chars > count)
			chars = count;
		if (chars > size)
			chars = size;
		count -= chars;
		written += chars;
		size = PIPE_HEAD(*inode);
		PIPE_HEAD(*inode) += chars;
		PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
		while (chars-->0)
			((char *)inode->i_size)[size++]=get_fs_byte(buf++);
	}
	wake_up(&inode->i_wait);
	return written;
}
Exemple #3
0
Fichier : pipe.c Projet : AmosZ/OS
int read_pipe(struct m_inode * inode, char * buf, int count)
{
	int chars, size, read = 0;

	while (count>0) {
		while (!(size=PIPE_SIZE(*inode))) {
			wake_up(&inode->i_wait);
			if (inode->i_count != 2) /* are there any writers? */
				return read;
			sleep_on(&inode->i_wait);
		}
		chars = PAGE_SIZE-PIPE_TAIL(*inode);
		if (chars > count)
			chars = count;
		if (chars > size)
			chars = size;
		count -= chars;
		read += chars;
		size = PIPE_TAIL(*inode);
		PIPE_TAIL(*inode) += chars;
		PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
		while (chars-->0)
			put_fs_byte(((char *)inode->i_size)[size++],buf++);
	}
	wake_up(&inode->i_wait);
	return read;
}
Exemple #4
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;
}
Exemple #5
0
static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
{
	struct new_stat tmp;
	unsigned int blocks, indirect;

	memset(&tmp, 0, sizeof(tmp));
	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
	tmp.st_ino = inode->i_ino;
	tmp.st_mode = inode->i_mode;
	tmp.st_nlink = inode->i_nlink;
	tmp.st_uid = inode->i_uid;
	tmp.st_gid = inode->i_gid;
	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
	tmp.st_size = inode->i_size;
	if (inode->i_pipe)
		tmp.st_size = PIPE_SIZE(*inode);
	tmp.st_atime = inode->i_atime;
	tmp.st_mtime = inode->i_mtime;
	tmp.st_ctime = inode->i_ctime;
/*
 * st_blocks and st_blksize are approximated with a simple algorithm if
 * they aren't supported directly by the filesystem. The minix and msdos
 * filesystems don't keep track of blocks, so they would either have to
 * be counted explicitly (by delving into the file itself), or by using
 * this simple algorithm to get a reasonable (although not 100% accurate)
 * value.
 */

/*
 * Use minix fs values for the number of direct and indirect blocks.  The
 * count is now exact for the minix fs except that it counts zero blocks.
 * Everything is in BLOCK_SIZE'd units until the assignment to
 * tmp.st_blksize.
 */
#define D_B   7
#define I_B   (BLOCK_SIZE / sizeof(unsigned short))

	if (!inode->i_blksize) {
		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
		if (blocks > D_B) {
			indirect = (blocks - D_B + I_B - 1) / I_B;
			blocks += indirect;
			if (indirect > 1) {
				indirect = (indirect - 1 + I_B - 1) / I_B;
				blocks += indirect;
				if (indirect > 1)
					blocks++;
			}
		}
		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
		tmp.st_blksize = BLOCK_SIZE;
	} else {
		tmp.st_blocks = inode->i_blocks;
		tmp.st_blksize = inode->i_blksize;
	}
	memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
Exemple #6
0
static int pipe_ioctl(struct inode *pino, struct file * filp,
		      unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
		case FIONREAD:
			return put_user(PIPE_SIZE(*pino),(int *) arg);
		default:
			return -EINVAL;
	}
}
Exemple #7
0
int PipePoll(struct File* file, struct PollItem* item, struct PollQueue* pollQueue)
{
	int mask = 0;
		
	if (file->vNode->mode & VFS_ATTR_READ)
	{
		if (PIPE_SIZE(file) > 0)
			item->revents = POLL_IN;
	}
	
	if (file->vNode->mode & VFS_ATTR_WRITE)
	{
		if (PIPE_MAX_WCHUNK(file) > 0)
			item->revents = POLL_OUT;
	}
	
	PollAddWait(pollQueue, &PIPE_WAIT(file));
	
	return mask;
}
Exemple #8
0
/*
 * For backward compatibility?  Maybe this should be moved
 * into arch/i386 instead?
 */
static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
{
	struct old_stat tmp;

	printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
		current->comm);
	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
	tmp.st_ino = inode->i_ino;
	tmp.st_mode = inode->i_mode;
	tmp.st_nlink = inode->i_nlink;
	tmp.st_uid = inode->i_uid;
	tmp.st_gid = inode->i_gid;
	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
	tmp.st_size = inode->i_size;
	if (inode->i_pipe)
		tmp.st_size = PIPE_SIZE(*inode);
	tmp.st_atime = inode->i_atime;
	tmp.st_mtime = inode->i_mtime;
	tmp.st_ctime = inode->i_ctime;
	memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
Exemple #9
0
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);
}