예제 #1
0
파일: file.c 프로젝트: cty12/ucore_plus
int file_seek(int fd, off_t pos, int whence)
{
	struct stat __stat, *stat = &__stat;
	int ret;
	struct file *file;
	if ((ret = fd2file(fd, &file)) != 0) {
		return ret;
	}
	filemap_acquire(file);

	switch (whence) {
	case LSEEK_SET:
		break;
	case LSEEK_CUR:
		pos += file->pos;
		break;
	case LSEEK_END:
		if ((ret = vop_fstat(file->node, stat)) == 0) {
			pos += stat->st_size;
		}
		break;
	default:
		ret = -E_INVAL;
	}

	if (ret == 0) {
		if ((ret = vop_tryseek(file->node, pos)) == 0) {
			file->pos = pos;
		}
	}
	filemap_release(file);
	return ret;
}
예제 #2
0
파일: file.c 프로젝트: cty12/ucore_plus
int file_fstat(int fd, struct stat *stat)
{
	int ret;
	struct file *file;
	if ((ret = fd2file(fd, &file)) != 0) {
		return ret;
	}
	filemap_acquire(file);
	ret = vop_fstat(file->node, stat);
	filemap_release(file);
	return ret;
}
예제 #3
0
파일: file.c 프로젝트: cty12/ucore_plus
int file_open(char *path, uint32_t open_flags)
{
	bool readable = 0, writable = 0;
	switch (open_flags & O_ACCMODE) {
	case O_RDONLY:
		readable = 1;
		break;
	case O_WRONLY:
		writable = 1;
		break;
	case O_RDWR:
		readable = writable = 1;
		break;
	default:
		return -E_INVAL;
	}

	int ret;
	struct file *file;
	if ((ret = filemap_alloc(NO_FD, &file)) != 0) {
		return ret;
	}

	struct inode *node;
	if ((ret = vfs_open(path, open_flags, &node)) != 0) {
		filemap_free(file);
		return ret;
	}

	file->pos = 0;
	if (open_flags & O_APPEND) {
		struct stat __stat, *stat = &__stat;
		if ((ret = vop_fstat(node, stat)) != 0) {
			vfs_close(node);
			filemap_free(file);
			return ret;
		}
		file->pos = stat->st_size;
	}

	file->node = node;
	file->readable = readable;
	file->writable = writable;
	filemap_open(file);
	return file->fd;
}
예제 #4
0
파일: file.c 프로젝트: tansinan/ucore_plus
int file_open(char *path, uint32_t open_flags)
{
	bool readable = 0, writable = 0;
	switch (open_flags & O_ACCMODE) {
	case O_RDONLY:
		readable = 1;
		break;
	case O_WRONLY:
		writable = 1;
		break;
	case O_RDWR:
		readable = writable = 1;
		break;
	default:
		return -E_INVAL;
	}
  //TODO: Implement other open flags.

  //Try to allocate a new kernel struct file object.
	struct file *file = kernel_file_pool_allocate();
  file_init(file);
  if(file == NULL) {
    return -E_NO_MEM;
  }
  file->readable = readable;
  file->writable = writable;

  //Allocate a new file descriptor
  struct file_desc_table *desc_table = fs_get_desc_table(current->fs_struct);
  int fd = file_desc_table_get_unused(desc_table);
  if(fd < 0) {
    return -E_MFILE;
  }

  int ret;
  //Allocate a new inode for the kernel file
	struct inode *node;
  ret = vfs_open(path, open_flags, &node);
	if (ret != 0) {
		kernel_file_pool_free(file);
		return ret;
	}

  //Initialize file state
	file->pos = 0;
	if (open_flags & O_APPEND) {
		struct stat __stat, *stat = &__stat;
		if ((ret = vop_fstat(node, stat)) != 0) {
			vfs_close(node);
			kernel_file_pool_free(file);
			return ret;
		}
		file->pos = stat->st_size;
	}

  //Associate the file descriptor with kernel file object
  file_desc_table_associate(desc_table, fd, file);

	file->node = node;
  file->io_flags = 0;
	return fd;
}