📄 main.c
字号:
/* * Copyright (c) 2005-2007, Kohsuke Ohtani * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * main.c - File system server *//* * All file systems work as a sub-modules under VFS (Virtual File System). * The routines in this file have the responsible to the following jobs. * * - Interpret the IPC message and pass the request into VFS routines. * - Validate the some of passed arguments in the message. * - Mapping of the task ID and cwd/file pointers. * * Note: All path string is translated to the full path before passing * it to the sys_* routines. */#include <prex/prex.h>#include <server/fs.h>#include <sys/list.h>#include <sys/stat.h>#include <sys/vnode.h>#include <sys/mount.h>#include <sys/file.h>#include <sys/syslog.h>#include <limits.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include "vfs.h"#if NR_FS_THREADS > 1extern int __isthreaded; /* thread option in libc */#endif/* * Message mapping */struct msg_map { int code; int (*func)();};/* Object for file service */static object_t fs_obj;static int fs_mount(tcb_t tcb, struct mount_msg *msg){ cap_t cap; int err; /* Check mount capability. */ if (task_getcap(msg->hdr.task, &cap)) return EINVAL; if ((cap & CAP_FS_MOUNT) == 0) return EPERM; err = sys_mount(msg->dev, msg->dir, msg->fs, msg->flags, (void *)msg->data);#ifdef DEBUG if (err) syslog(LOG_INFO, "fs: mount failed! fs=%s\n", msg->fs);#endif return err;}static int fs_umount(tcb_t tcb, struct path_msg *msg){ cap_t cap; /* Check mount capability. */ if (task_getcap(msg->hdr.task, &cap)) return EINVAL; if ((cap & CAP_FS_MOUNT) == 0) return EPERM; return sys_umount(msg->path);}static int fs_sync(tcb_t tcb, struct msg *msg){ return sys_sync();}static int fs_open(tcb_t tcb, struct open_msg *msg){ char path[PATH_MAX]; file_t fp; int fd, err; /* Find empty slot for file descriptor */ for (fd = 0; fd < OPEN_MAX; fd++) if (tcb->file[fd] == NULL) break; if (fd == OPEN_MAX) return EMFILE; if ((err = tcb_conv(tcb, msg->path, path)) != 0) return err; if ((err = sys_open(path, msg->flags, msg->mode, &fp)) != 0) return err; tcb->file[fd] = fp; tcb->nr_open++; msg->fd = fd; return 0;}static int fs_close(tcb_t tcb, struct msg *msg){ file_t fp; int fd, err; fd = msg->data[0]; if (fd >= OPEN_MAX) return EBADF; fp = tcb->file[fd]; if (!fp) return EBADF; if ((err = sys_close(fp)) != 0) return err; tcb->file[fd] = NULL; tcb->nr_open--; return 0;}static int fs_mknod(tcb_t tcb, struct open_msg *msg){ char path[PATH_MAX]; int err; if ((err = tcb_conv(tcb, msg->path, path)) != 0) return err; return sys_mknod(path, msg->mode);}static int fs_lseek(tcb_t tcb, struct msg *msg){ file_t fp; off_t offset, org; int err, type; if ((fp = tcb_getfp(tcb, msg->data[0])) == NULL) return EBADF; offset = (off_t)msg->data[1]; type = msg->data[2]; err = sys_lseek(fp, offset, type, &org); msg->data[0] = (int)org; return err;}static int fs_read(tcb_t tcb, struct io_msg *msg){ file_t fp; void *buf; size_t size, bytes; int err; if ((fp = tcb_getfp(tcb, msg->fd)) == NULL) return EBADF; size = msg->size; if ((err = vm_map(msg->hdr.task, msg->buf, size, &buf)) != 0) return EFAULT; err = sys_read(fp, buf, size, &bytes); msg->size = bytes; vm_free(task_self(), buf); return err;}static int fs_write(tcb_t tcb, struct io_msg *msg){ file_t fp; void *buf; size_t size, bytes; int err; if ((fp = tcb_getfp(tcb, msg->fd)) == NULL) return EBADF; size = msg->size; if ((err = vm_map(msg->hdr.task, msg->buf, size, &buf)) != 0) return EFAULT; err = sys_write(fp, buf, size, &bytes); msg->size = bytes; vm_free(task_self(), buf); return err;}static int fs_ioctl(tcb_t tcb, struct msg *msg){ /* XXX */ return 0;}static int fs_fsync(tcb_t tcb, struct msg *msg){ file_t fp; if ((fp = tcb_getfp(tcb, msg->data[0])) == NULL) return EBADF; return sys_fsync(fp);}static int fs_fstat(tcb_t tcb, struct stat_msg *msg){ file_t fp; struct stat *st; if ((fp = tcb_getfp(tcb, msg->fd)) == NULL) return EBADF; st = &msg->st; return sys_fstat(fp, st);}static int fs_opendir(tcb_t tcb, struct open_msg *msg){ char path[PATH_MAX]; file_t fp; int fd, err; /* Find empty slot for file structure */ for (fd = 0; fd < OPEN_MAX; fd++) if (tcb->file[fd] == NULL) break; if (fd == OPEN_MAX) return EMFILE; /* Get the mounted file system and node */ if ((err = tcb_conv(tcb, msg->path, path)) != 0) return err; if ((err = sys_opendir(path, &fp)) != 0) return err; tcb->file[fd] = fp; msg->fd = fd; return 0;}static int fs_closedir(tcb_t tcb, struct msg *msg){ file_t fp; int fd, err; fd = msg->data[0]; if (fd >= OPEN_MAX) return EBADF; fp = tcb->file[fd]; if (fp == NULL) return EBADF; if ((err = sys_closedir(fp)) != 0) return err; tcb->file[fd] = NULL; return 0;}static int fs_readdir(tcb_t tcb, struct dir_msg *msg){ file_t fp; if ((fp = tcb_getfp(tcb, msg->fd)) == NULL) return EBADF; return sys_readdir(fp, &msg->dirent);}static int fs_rewinddir(tcb_t tcb, struct msg *msg){ file_t fp; if ((fp = tcb_getfp(tcb, msg->data[0])) == NULL) return EBADF; return sys_rewinddir(fp);}static int fs_seekdir(tcb_t tcb, struct msg *msg){ file_t fp; long loc; if ((fp = tcb_getfp(tcb, msg->data[0])) == NULL) return EBADF; loc = msg->data[1]; return sys_seekdir(fp, loc);}static int fs_telldir(tcb_t tcb, struct msg *msg){ file_t fp; long loc; int err; if ((fp = tcb_getfp(tcb, msg->data[0])) == NULL) return EBADF; loc = msg->data[1]; if ((err = sys_telldir(fp, &loc)) != 0) return err; msg->data[0] = loc; return 0;}static int fs_mkdir(tcb_t tcb, struct open_msg *msg){ char path[PATH_MAX]; int err; if ((err = tcb_conv(tcb, msg->path, path)) != 0) return err; return sys_mkdir(path, msg->mode);}static int fs_rmdir(tcb_t tcb, struct path_msg *msg){ char path[PATH_MAX]; int err; if (msg->path == NULL) return ENOENT; if ((err = tcb_conv(tcb, msg->path, path)) != 0) return err; return sys_rmdir(path);}static int fs_rename(tcb_t tcb, struct path_msg *msg){ char src[PATH_MAX]; char dest[PATH_MAX]; int err; if (msg->path == NULL || msg->path2 == NULL) return ENOENT; if ((err = tcb_conv(tcb, msg->path, src)) != 0) return err; if ((err = tcb_conv(tcb, msg->path2, dest)) != 0) return err; return sys_rename(src, dest);}static int fs_chdir(tcb_t tcb, struct path_msg *msg){ char path[PATH_MAX]; file_t fp; int err; if (msg->path == NULL) return ENOENT; if ((err = tcb_conv(tcb, msg->path, path)) != 0) return err; /* Check if directory exits */ if ((err = sys_opendir(path, &fp)) != 0) return err; if (tcb->cwd_fp) sys_closedir(tcb->cwd_fp); tcb->cwd_fp = fp; strcpy(tcb->cwd, path); return 0;}static int fs_link(tcb_t tcb, struct msg *msg){ /* XXX */ return EPERM;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -