⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysfile.c

📁 美国mit操作系统课程所用的一个教学操作系统xv6
💻 C
字号:
#include "types.h"#include "defs.h"#include "param.h"#include "stat.h"#include "mmu.h"#include "proc.h"#include "fs.h"#include "fsvar.h"#include "file.h"#include "fcntl.h"// Fetch the nth word-sized system call argument as a file descriptor// and return both the descriptor and the corresponding struct file.static intargfd(int n, int *pfd, struct file **pf){  int fd;  struct file *f;  if(argint(n, &fd) < 0)    return -1;  if(fd < 0 || fd >= NOFILE || (f=cp->ofile[fd]) == 0)    return -1;  if(pfd)    *pfd = fd;  if(pf)    *pf = f;  return 0;}// Allocate a file descriptor for the given file.// Takes over file reference from caller on success.static intfdalloc(struct file *f){  int fd;  for(fd = 0; fd < NOFILE; fd++){    if(cp->ofile[fd] == 0){      cp->ofile[fd] = f;      return fd;    }  }  return -1;}intsys_read(void){  struct file *f;  int n;  char *p;  if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0)    return -1;  return fileread(f, p, n);}intsys_write(void){  struct file *f;  int n;  char *p;  if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0)    return -1;  return filewrite(f, p, n);}intsys_dup(void){  struct file *f;  int fd;    if(argfd(0, 0, &f) < 0)    return -1;  if((fd=fdalloc(f)) < 0)    return -1;  filedup(f);  return fd;}intsys_close(void){  int fd;  struct file *f;    if(argfd(0, &fd, &f) < 0)    return -1;  cp->ofile[fd] = 0;  fileclose(f);  return 0;}intsys_fstat(void){  struct file *f;  struct stat *st;    if(argfd(0, 0, &f) < 0 || argptr(1, (void*)&st, sizeof(*st)) < 0)    return -1;  return filestat(f, st);}// Create the path new as a link to the same inode as old.intsys_link(void){  char name[DIRSIZ], *new, *old;  struct inode *dp, *ip;  if(argstr(0, &old) < 0 || argstr(1, &new) < 0)    return -1;  if((ip = namei(old)) == 0)    return -1;  ilock(ip);  if(ip->type == T_DIR){    iunlockput(ip);    return -1;  }  ip->nlink++;  iupdate(ip);  iunlock(ip);  if((dp = nameiparent(new, name)) == 0)    goto  bad;  ilock(dp);  if(dp->dev != ip->dev || dirlink(dp, name, ip->inum) < 0)    goto bad;  iunlockput(dp);  iput(ip);  return 0;bad:  if(dp)    iunlockput(dp);  ilock(ip);  ip->nlink--;  iupdate(ip);  iunlockput(ip);  return -1;}// Is the directory dp empty except for "." and ".." ?static intisdirempty(struct inode *dp){  int off;  struct dirent de;  for(off=2*sizeof(de); off<dp->size; off+=sizeof(de)){    if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))      panic("isdirempty: readi");    if(de.inum != 0)      return 0;  }  return 1;}intsys_unlink(void){  struct inode *ip, *dp;  struct dirent de;  char name[DIRSIZ], *path;  uint off;  if(argstr(0, &path) < 0)    return -1;  if((dp = nameiparent(path, name)) == 0)    return -1;  ilock(dp);  // Cannot unlink "." or "..".  if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0){    iunlockput(dp);    return -1;  }  if((ip = dirlookup(dp, name, &off)) == 0){    iunlockput(dp);    return -1;  }  ilock(ip);  if(ip->nlink < 1)    panic("unlink: nlink < 1");  if(ip->type == T_DIR && !isdirempty(ip)){    iunlockput(ip);    iunlockput(dp);    return -1;  }  memset(&de, 0, sizeof(de));  if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))    panic("unlink: writei");  iunlockput(dp);  ip->nlink--;  iupdate(ip);  iunlockput(ip);  return 0;}static struct inode*create(char *path, int canexist, short type, short major, short minor){  uint off;  struct inode *ip, *dp;  char name[DIRSIZ];  if((dp = nameiparent(path, name)) == 0)    return 0;  ilock(dp);  if(canexist && (ip = dirlookup(dp, name, &off)) != 0){    iunlockput(dp);    ilock(ip);    if(ip->type != type || ip->major != major || ip->minor != minor){      iunlockput(ip);      return 0;    }    return ip;  }  if((ip = ialloc(dp->dev, type)) == 0){    iunlockput(dp);    return 0;  }  ilock(ip);  ip->major = major;  ip->minor = minor;  ip->nlink = 1;  iupdate(ip);    if(dirlink(dp, name, ip->inum) < 0){    ip->nlink = 0;    iunlockput(ip);    iunlockput(dp);    return 0;  }  if(type == T_DIR){  // Create . and .. entries.    dp->nlink++;  // for ".."    iupdate(dp);    // No ip->nlink++ for ".": avoid cyclic ref count.    if(dirlink(ip, ".", ip->inum) < 0 || dirlink(ip, "..", dp->inum) < 0)      panic("create dots");  }  iunlockput(dp);  return ip;}intsys_open(void){  char *path;  int fd, omode;  struct file *f;  struct inode *ip;  if(argstr(0, &path) < 0 || argint(1, &omode) < 0)    return -1;  if(omode & O_CREATE){    if((ip = create(path, 1, T_FILE, 0, 0)) == 0)      return -1;  } else {    if((ip = namei(path)) == 0)      return -1;    ilock(ip);    if(ip->type == T_DIR && (omode & (O_RDWR|O_WRONLY))){      iunlockput(ip);      return -1;    }  }  if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){    if(f)      fileclose(f);    iunlockput(ip);    return -1;  }  iunlock(ip);  f->type = FD_INODE;  f->ip = ip;  f->off = 0;  f->readable = !(omode & O_WRONLY);  f->writable = (omode & O_WRONLY) || (omode & O_RDWR);  return fd;}intsys_mknod(void){  struct inode *ip;  char *path;  int len;  int major, minor;    if((len=argstr(0, &path)) < 0 ||     argint(1, &major) < 0 ||     argint(2, &minor) < 0 ||     (ip = create(path, 0, T_DEV, major, minor)) == 0)    return -1;  iunlockput(ip);  return 0;}intsys_mkdir(void){  char *path;  struct inode *ip;  if(argstr(0, &path) < 0 || (ip = create(path, 0, T_DIR, 0, 0)) == 0)    return -1;  iunlockput(ip);  return 0;}intsys_chdir(void){  char *path;  struct inode *ip;  if(argstr(0, &path) < 0 || (ip = namei(path)) == 0)    return -1;  ilock(ip);  if(ip->type != T_DIR){    iunlockput(ip);    return -1;  }  iunlock(ip);  iput(cp->cwd);  cp->cwd = ip;  return 0;}intsys_exec(void){  char *path, *argv[20];  int i;  uint uargv, uarg;  if(argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0)    return -1;  memset(argv, 0, sizeof(argv));  for(i=0;; i++){    if(i >= NELEM(argv))      return -1;    if(fetchint(cp, uargv+4*i, (int*)&uarg) < 0)      return -1;    if(uarg == 0){      argv[i] = 0;      break;    }    if(fetchstr(cp, uarg, &argv[i]) < 0)      return -1;  }  return exec(path, argv);}intsys_pipe(void){  int *fd;  struct file *rf, *wf;  int fd0, fd1;  if(argptr(0, (void*)&fd, 2*sizeof(fd[0])) < 0)    return -1;  if(pipealloc(&rf, &wf) < 0)    return -1;  fd0 = -1;  if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){    if(fd0 >= 0)      cp->ofile[fd0] = 0;    fileclose(rf);    fileclose(wf);    return -1;  }  fd[0] = fd0;  fd[1] = fd1;  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -