예제 #1
0
파일: fd.cpp 프로젝트: looncraz/haiku
fssh_ssize_t
_kern_write(int fd, fssh_off_t pos, const void *buffer, fssh_size_t length)
{
	struct file_descriptor *descriptor;
	fssh_ssize_t bytesWritten;

	descriptor = get_fd(get_current_io_context(true), fd);
	if (descriptor == NULL)
		return FSSH_B_FILE_ERROR;
	if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_RDONLY) {
		put_fd(descriptor);
		return FSSH_B_FILE_ERROR;
	}

	if (pos == -1)
		pos = descriptor->pos;

	if (descriptor->ops->fd_write) {
		bytesWritten = descriptor->ops->fd_write(descriptor, pos, buffer, &length);
		if (bytesWritten >= FSSH_B_OK) {
			if (length > FSSH_SSIZE_MAX)
				bytesWritten = FSSH_SSIZE_MAX;
			else
				bytesWritten = (fssh_ssize_t)length;

			descriptor->pos = pos + length;
		}
	} else
		bytesWritten = FSSH_B_BAD_VALUE;

	put_fd(descriptor);
	return bytesWritten;
}
예제 #2
0
파일: fd.cpp 프로젝트: simonsouth/haiku
ssize_t
_kern_read_dir(int fd, struct dirent* buffer, size_t bufferSize,
	uint32 maxCount)
{
	struct file_descriptor* descriptor;
	ssize_t retval;

	TRACE(("sys_read_dir(fd = %d, buffer = %p, bufferSize = %ld, count = "
		"%lu)\n",fd, buffer, bufferSize, maxCount));

	struct io_context* ioContext = get_current_io_context(true);
	descriptor = get_fd(ioContext, fd);
	if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0)
		return B_FILE_ERROR;

	if (descriptor->ops->fd_read_dir) {
		uint32 count = maxCount;
		retval = descriptor->ops->fd_read_dir(ioContext, descriptor, buffer,
			bufferSize, &count);
		if (retval >= 0)
			retval = count;
	} else
		retval = B_UNSUPPORTED;

	put_fd(descriptor);
	return retval;
}
예제 #3
0
파일: sysfile.c 프로젝트: 7perl/akaros
void fdclose(struct fgrp *f, int fd)
{
	
	int i;
	struct chan *c;

	spin_lock(&f->lock);
	if (f->closed) {
		spin_unlock(&f->lock);
		return;
	}
	c = f->fd[fd];
	if (c == 0) {
		/* can happen for users with shared fd tables */
		spin_unlock(&f->lock);
		return;
	}
	f->fd[fd] = 0;
	if (fd == f->maxfd)
		for (i = fd; --i >= 0 && f->fd[i] == 0;)
			f->maxfd = i;
	if (fd < f->minfd)
		f->minfd = fd;
	/* VFS hack: give the FD back to VFS */
	put_fd(&current->open_files, fd);
	spin_unlock(&f->lock);
	cclose(c);
}
예제 #4
0
파일: fd.cpp 프로젝트: simonsouth/haiku
static int
dup_fd(int fd, bool kernel)
{
	struct io_context* context = get_current_io_context(kernel);
	struct file_descriptor* descriptor;
	int status;

	TRACE(("dup_fd: fd = %d\n", fd));

	// Try to get the fd structure
	descriptor = get_fd(context, fd);
	if (descriptor == NULL)
		return B_FILE_ERROR;

	// now put the fd in place
	status = new_fd(context, descriptor);
	if (status < 0)
		put_fd(descriptor);
	else {
		mutex_lock(&context->io_mutex);
		fd_set_close_on_exec(context, status, false);
		mutex_unlock(&context->io_mutex);
	}

	return status;
}
예제 #5
0
파일: fd.cpp 프로젝트: simonsouth/haiku
/*!	POSIX says this should be the same as:
		close(newfd);
		fcntl(oldfd, F_DUPFD, newfd);

	We do dup2() directly to be thread-safe.
*/
static int
dup2_fd(int oldfd, int newfd, bool kernel)
{
	struct file_descriptor* evicted = NULL;
	struct io_context* context;

	TRACE(("dup2_fd: ofd = %d, nfd = %d\n", oldfd, newfd));

	// quick check
	if (oldfd < 0 || newfd < 0)
		return B_FILE_ERROR;

	// Get current I/O context and lock it
	context = get_current_io_context(kernel);
	mutex_lock(&context->io_mutex);

	// Check if the fds are valid (mutex must be locked because
	// the table size could be changed)
	if ((uint32)oldfd >= context->table_size
		|| (uint32)newfd >= context->table_size
		|| context->fds[oldfd] == NULL
		|| (context->fds[oldfd]->open_mode & O_DISCONNECTED) != 0) {
		mutex_unlock(&context->io_mutex);
		return B_FILE_ERROR;
	}

	// Check for identity, note that it cannot be made above
	// because we always want to return an error on invalid
	// handles
	select_info* selectInfos = NULL;
	if (oldfd != newfd) {
		// Now do the work
		TFD(Dup2FD(context, oldfd, newfd));

		evicted = context->fds[newfd];
		selectInfos = context->select_infos[newfd];
		context->select_infos[newfd] = NULL;
		atomic_add(&context->fds[oldfd]->ref_count, 1);
		atomic_add(&context->fds[oldfd]->open_count, 1);
		context->fds[newfd] = context->fds[oldfd];

		if (evicted == NULL)
			context->num_used_fds++;
	}

	fd_set_close_on_exec(context, newfd, false);

	mutex_unlock(&context->io_mutex);

	// Say bye bye to the evicted fd
	if (evicted) {
		deselect_select_infos(evicted, selectInfos, true);
		close_fd(evicted);
		put_fd(evicted);
	}

	return newfd;
}
예제 #6
0
파일: fd.cpp 프로젝트: looncraz/haiku
bool
fd_is_valid(int fd, bool kernel)
{
	struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel), fd);
	if (descriptor == NULL)
		return false;

	put_fd(descriptor);
	return true;
}
예제 #7
0
파일: fd.cpp 프로젝트: looncraz/haiku
fssh_ssize_t
_kern_writev(int fd, fssh_off_t pos, const fssh_iovec *vecs, fssh_size_t count)
{
	struct file_descriptor *descriptor;
	fssh_ssize_t bytesWritten = 0;
	fssh_status_t status;
	uint32_t i;

	descriptor = get_fd(get_current_io_context(true), fd);
	if (!descriptor)
		return FSSH_B_FILE_ERROR;
	if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_RDONLY) {
		put_fd(descriptor);
		return FSSH_B_FILE_ERROR;
	}

	if (pos == -1)
		pos = descriptor->pos;

	if (descriptor->ops->fd_write) {
		for (i = 0; i < count; i++) {
			fssh_size_t length = vecs[i].iov_len;
			status = descriptor->ops->fd_write(descriptor, pos, vecs[i].iov_base, &length);
			if (status < FSSH_B_OK) {
				bytesWritten = status;
				break;
			}

			if ((uint32_t)bytesWritten + length > FSSH_SSIZE_MAX)
				bytesWritten = FSSH_SSIZE_MAX;
			else
				bytesWritten += (fssh_ssize_t)length;

			pos += vecs[i].iov_len;
		}
	} else
		bytesWritten = FSSH_B_BAD_VALUE;

	descriptor->pos = pos;
	put_fd(descriptor);
	return bytesWritten;
}
예제 #8
0
파일: fd.cpp 프로젝트: simonsouth/haiku
/*!	This function checks if the specified fd is valid in the current
	context. It can be used for a quick check; the fd is not locked
	so it could become invalid immediately after this check.
*/
bool
fd_is_valid(int fd, bool kernel)
{
	struct file_descriptor* descriptor
		= get_fd(get_current_io_context(kernel), fd);
	if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0)
		return false;

	put_fd(descriptor);
	return true;
}
예제 #9
0
파일: fd.cpp 프로젝트: simonsouth/haiku
status_t
close_fd_index(struct io_context* context, int fd)
{
	struct file_descriptor* descriptor = remove_fd(context, fd);

	if (descriptor == NULL)
		return B_FILE_ERROR;

	close_fd(descriptor);
	put_fd(descriptor);
		// the reference associated with the slot

	return B_OK;
}
예제 #10
0
파일: vm.c 프로젝트: Hooman3/minix
static int
vm_mmap_out(struct trace_proc * proc, const message * m_out)
{

	if (m_out->m_mmap.flags & MAP_THIRDPARTY)
		put_endpoint(proc, "forwhom", m_out->m_mmap.forwhom);
	put_ptr(proc, "addr", (vir_bytes)m_out->m_mmap.addr);
	put_value(proc, "len", "%zu", m_out->m_mmap.len);
	put_flags(proc, "prot", mmap_prot, COUNT(mmap_prot), "0x%x",
	    m_out->m_mmap.prot);
	put_flags(proc, "flags", mmap_flags, COUNT(mmap_flags), "0x%x",
	    m_out->m_mmap.flags);
	put_fd(proc, "fd", m_out->m_mmap.fd);
	put_value(proc, "offset", "%"PRId64, m_out->m_mmap.offset);

	return CT_DONE;
}
예제 #11
0
파일: fd.cpp 프로젝트: simonsouth/haiku
off_t
_kern_seek(int fd, off_t pos, int seekType)
{
	struct file_descriptor* descriptor;

	descriptor = get_fd(get_current_io_context(true), fd);
	if (!descriptor)
		return B_FILE_ERROR;

	if (descriptor->ops->fd_seek)
		pos = descriptor->ops->fd_seek(descriptor, pos, seekType);
	else
		pos = ESPIPE;

	put_fd(descriptor);
	return pos;
}
예제 #12
0
static status_t
get_socket_descriptor(int fd, bool kernel, file_descriptor*& descriptor)
{
	if (fd < 0)
		return EBADF;

	descriptor = get_fd(get_current_io_context(kernel), fd);
	if (descriptor == NULL)
		return EBADF;

	if (descriptor->type != FDTYPE_SOCKET) {
		put_fd(descriptor);
		return ENOTSOCK;
	}

	return B_OK;
}
예제 #13
0
파일: fd.cpp 프로젝트: mmanley/Antares
static status_t
fd_ioctl(bool kernelFD, int fd, ulong op, void* buffer, size_t length)
{
	struct file_descriptor* descriptor;
	int status;

	descriptor = get_fd(get_current_io_context(kernelFD), fd);
	if (descriptor == NULL)
		return B_FILE_ERROR;

	if (descriptor->ops->fd_ioctl)
		status = descriptor->ops->fd_ioctl(descriptor, op, buffer, length);
	else
		status = EOPNOTSUPP;

	put_fd(descriptor);
	return status;
}
예제 #14
0
파일: fd.cpp 프로젝트: looncraz/haiku
fssh_status_t
_kern_ioctl(int fd, uint32_t op, void *buffer, fssh_size_t length)
{
	struct file_descriptor *descriptor;
	int status;

	TRACE(("sys_ioctl: fd %d\n", fd));

	descriptor = get_fd(get_current_io_context(true), fd);
	if (descriptor == NULL)
		return FSSH_B_FILE_ERROR;

	if (descriptor->ops->fd_ioctl)
		status = descriptor->ops->fd_ioctl(descriptor, op, buffer, length);
	else
		status = FSSH_EOPNOTSUPP;

	put_fd(descriptor);
	return status;
}
예제 #15
0
파일: fd.cpp 프로젝트: simonsouth/haiku
status_t
_user_rewind_dir(int fd)
{
	struct file_descriptor* descriptor;
	status_t status;

	TRACE(("user_rewind_dir(fd = %d)\n", fd));

	descriptor = get_fd(get_current_io_context(false), fd);
	if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0)
		return B_FILE_ERROR;

	if (descriptor->ops->fd_rewind_dir != NULL)
		status = descriptor->ops->fd_rewind_dir(descriptor);
	else
		status = B_UNSUPPORTED;

	put_fd(descriptor);
	return status;
}
예제 #16
0
파일: fd.cpp 프로젝트: looncraz/haiku
static fssh_status_t
common_close(int fd, bool kernel)
{
	struct io_context *io = get_current_io_context(kernel);
	struct file_descriptor *descriptor = remove_fd(io, fd);

	if (descriptor == NULL)
		return FSSH_B_FILE_ERROR;

#ifdef TRACE_FD
	if (!kernel)
		TRACE(("_user_close(descriptor = %p)\n", descriptor));
#endif

	close_fd(descriptor);
	put_fd(descriptor);
		// the reference associated with the slot

	return FSSH_B_OK;
}
예제 #17
0
파일: fd.cpp 프로젝트: looncraz/haiku
fssh_status_t
_kern_rewind_dir(int fd)
{
	struct file_descriptor *descriptor;
	fssh_status_t status;

	TRACE(("sys_rewind_dir(fd = %d)\n",fd));

	descriptor = get_fd(get_current_io_context(true), fd);
	if (descriptor == NULL)
		return FSSH_B_FILE_ERROR;

	if (descriptor->ops->fd_rewind_dir)
		status = descriptor->ops->fd_rewind_dir(descriptor);
	else
		status = FSSH_EOPNOTSUPP;

	put_fd(descriptor);
	return status;
}
예제 #18
0
파일: fd.cpp 프로젝트: mmanley/Antares
status_t
_user_rewind_dir(int fd)
{
	struct file_descriptor* descriptor;
	status_t status;

	TRACE(("user_rewind_dir(fd = %d)\n", fd));

	descriptor = get_fd(get_current_io_context(false), fd);
	if (descriptor == NULL)
		return B_FILE_ERROR;

	if (descriptor->ops->fd_rewind_dir)
		status = descriptor->ops->fd_rewind_dir(descriptor);
	else
		status = EOPNOTSUPP;

	put_fd(descriptor);
	return status;
}
예제 #19
0
파일: fd.cpp 프로젝트: simonsouth/haiku
off_t
_user_seek(int fd, off_t pos, int seekType)
{
	syscall_64_bit_return_value();

	struct file_descriptor* descriptor;

	descriptor = get_fd(get_current_io_context(false), fd);
	if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0)
		return B_FILE_ERROR;

	TRACE(("user_seek(descriptor = %p)\n", descriptor));

	if (descriptor->ops->fd_seek != NULL)
		pos = descriptor->ops->fd_seek(descriptor, pos, seekType);
	else
		pos = ESPIPE;

	put_fd(descriptor);
	return pos;
}
예제 #20
0
파일: fd.cpp 프로젝트: simonsouth/haiku
static status_t
fd_ioctl(bool kernelFD, int fd, uint32 op, void* buffer, size_t length)
{
	struct file_descriptor* descriptor;
	int status;

	descriptor = get_fd(get_current_io_context(kernelFD), fd);
	if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0)
		return B_FILE_ERROR;

	if (descriptor->ops->fd_ioctl != NULL)
		status = descriptor->ops->fd_ioctl(descriptor, op, buffer, length);
	else
		status = B_DEV_INVALID_IOCTL;

	if (status == B_DEV_INVALID_IOCTL)
		status = ENOTTY;

	put_fd(descriptor);
	return status;
}
예제 #21
0
static status_t
do_iterative_fd_io_finish(void* _cookie, io_request* request, status_t status,
	bool partialTransfer, generic_size_t transferEndOffset)
{
	iterative_io_cookie* cookie = (iterative_io_cookie*)_cookie;

	if (cookie->finished != NULL) {
		cookie->finished(cookie->cookie, request, status, partialTransfer,
			transferEndOffset);
	}

	put_fd(cookie->descriptor);

	if (cookie->next_finished_callback != NULL) {
		cookie->next_finished_callback(cookie->next_finished_cookie, request,
			status, partialTransfer, transferEndOffset);
	}

	delete cookie;

	return B_OK;
}
예제 #22
0
파일: fd.cpp 프로젝트: looncraz/haiku
fssh_ssize_t
_kern_read_dir(int fd, struct fssh_dirent *buffer, fssh_size_t bufferSize, uint32_t maxCount)
{
	struct file_descriptor *descriptor;
	fssh_ssize_t retval;

	TRACE(("sys_read_dir(fd = %d, buffer = %p, bufferSize = %ld, count = %lu)\n",fd, buffer, bufferSize, maxCount));

	descriptor = get_fd(get_current_io_context(true), fd);
	if (descriptor == NULL)
		return FSSH_B_FILE_ERROR;

	if (descriptor->ops->fd_read_dir) {
		uint32_t count = maxCount;
		retval = descriptor->ops->fd_read_dir(descriptor, buffer, bufferSize, &count);
		if (retval >= 0)
			retval = count;
	} else
		retval = FSSH_EOPNOTSUPP;

	put_fd(descriptor);
	return retval;
}
예제 #23
0
파일: fd.cpp 프로젝트: simonsouth/haiku
	inline void Unlock(file_descriptor* lockable)
	{
		put_fd(lockable);
	}
예제 #24
0
	~FDPutter()
	{
		if (descriptor != NULL)
			put_fd(descriptor);
	}