/********************************************************************************************************* ** Function name: __vfs_close ** Descriptions: 关闭文件 ** input parameters: pid 任务 ID ** fd 文件描述符 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int __vfs_close(pid_t pid, int fd) { int ret; vfs_file_begin(pid); if (point->fs->close == NULL) { vfs_file_end(pid); seterrno(ENOSYS); return -1; } seterrno(0); if (atomic_dec_and_test(&file->ref)) { ret = point->fs->close(point, file); if (ret == 0) { mutex_lock(&info_lock[pid], 0); info->files[fd] = NULL; mutex_unlock(&info_lock[pid]); vfs_file_free(file); atomic_dec(&point->ref); return ret; } else { atomic_inc(&file->ref); } } else { ret = 0; } vfs_file_end(pid); return ret; }
int main(int argc, char *argv[]) { FILE *general = fopen("../data/GENERAL.MIX", "rb"); if (!general) { perror("Can't open GENERAL.MIX"); return 1; } fseek(general, 0, SEEK_END); size_t size = ftell(general); fseek(general, 0, SEEK_SET); char *buf = g_malloc(size); fread(buf, 1, size, general); fclose(general); vfs_file_t *fp = vfs_memfile_new(size); vfs_file_write(buf, size, fp); vfs_file_seek(fp, 0, VFS_SEEK_SET); vfs_mix_archive_t *ar = vfs_mix_archive_new(fp); printf("Archive has %u files.\n", *(guint16*)ar); vfs_file_t *ini = vfs_mix_archive_fopen(ar, "scg01ea.ini"); vfs_file_seek(ini, 0, VFS_SEEK_END); guint32 inisize = vfs_file_tell(ini); vfs_file_seek(ini, 0, VFS_SEEK_SET); char *inibuf = g_malloc0(inisize+1); vfs_file_read(inibuf, inisize, ini); printf(inibuf); vfs_file_free(ini); return 0; };
/********************************************************************************************************* ** Function name: vfs_open ** Descriptions: 打开文件 ** input parameters: path 文件路径 ** oflag 标志 ** mode 模式 ** output parameters: NONE ** Returned value: 0 OR -1 *********************************************************************************************************/ int vfs_open(const char *path, int oflag, mode_t mode) { mount_point_t *point; vfs_info_t *info; file_t *file; char *pathbuf; char *filepath; int fd; int ret; int pid = getpid(); pathbuf = kmalloc(PATH_BUF_LEN, GFP_KERNEL); if (pathbuf == NULL) { seterrno(ENOMEM); return -1; } point = vfs_mount_point_lookup_ref(pathbuf, &filepath, path); /* 查找挂载点 */ if (point == NULL) { kfree(pathbuf); return -1; } mutex_lock(&info_lock[pid], 0); info = infos[pid]; for (fd = 0; fd < info->open_max; fd++) { /* 查找一个空闲的文件描述符 */ file = info->files[fd]; if (file == NULL) { break; } } if (fd == info->open_max) { /* 没找到 */ mutex_unlock(&info_lock[pid]); atomic_dec(&point->ref); kfree(pathbuf); seterrno(EMFILE); return -1; } file = vfs_file_alloc(); /* 分配一个文件结构 */ if (file == NULL) { mutex_unlock(&info_lock[pid]); atomic_dec(&point->ref); kfree(pathbuf); seterrno(EMFILE); return -1; } info->files[fd] = file; /* 记录下来 */ mutex_lock(&file->lock, 0); /* 锁上文件结构 */ mutex_unlock(&info_lock[pid]); file->type = VFS_FILE_TYPE_FILE; /* 类型: 文件 */ file->flags = (oflag + 1); /* 打开标志 */ file->ctx = NULL; /* 上下文 */ file->point = point; /* 挂载点 */ if (point->fs->open == NULL) { mutex_lock(&info_lock[pid], 0); info->files[fd] = NULL; mutex_unlock(&info_lock[pid]); vfs_file_free(file); atomic_dec(&point->ref); kfree(pathbuf); seterrno(ENOSYS); return -1; } seterrno(0); ret = point->fs->open(point, file, filepath, oflag, mode); /* 打开文件 */ if (ret < 0) { mutex_lock(&info_lock[pid], 0); info->files[fd] = NULL; mutex_unlock(&info_lock[pid]); vfs_file_free(file); atomic_dec(&point->ref); kfree(pathbuf); return -1; } mutex_unlock(&file->lock); kfree(pathbuf); return fd; /* 返回文件描述符 */ }