diff options
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | defs.h | 3 | ||||
| -rw-r--r-- | fd.c | 13 | ||||
| -rw-r--r-- | fs.c | 11 | ||||
| -rw-r--r-- | ls.c | 43 | ||||
| -rw-r--r-- | stat.h | 7 | ||||
| -rw-r--r-- | syscall.c | 26 | ||||
| -rw-r--r-- | syscall.h | 1 | ||||
| -rw-r--r-- | user.h | 2 | ||||
| -rw-r--r-- | userfs.c | 3 | ||||
| -rw-r--r-- | usys.S | 3 | 
11 files changed, 115 insertions, 5 deletions
| @@ -87,11 +87,15 @@ sh : sh.o $(ULIB)  	$(LD) -N -e main -Ttext 0 -o sh sh.o $(ULIB)  	$(OBJDUMP) -S sh > sh.asm +ls : ls.o $(ULIB) +	$(LD) -N -e main -Ttext 0 -o ls ls.o $(ULIB) +	$(OBJDUMP) -S ls > ls.asm +  mkfs : mkfs.c fs.h  	cc -o mkfs mkfs.c -fs.img : mkfs userfs usertests echo cat README init sh -	./mkfs fs.img userfs usertests echo cat README init sh +fs.img : mkfs userfs usertests echo cat README init sh ls +	./mkfs fs.img userfs usertests echo cat README init sh ls  -include *.d @@ -85,12 +85,14 @@ int pipe_write(struct pipe *p, char *addr, int n);  int pipe_read(struct pipe *p, char *addr, int n);  // fd.c +struct stat;  void fd_init(void);  int fd_ualloc(void);  struct fd * fd_alloc(void);  void fd_close(struct fd *);  int fd_read(struct fd *fd, char *addr, int n);  int fd_write(struct fd *fd, char *addr, int n); +int fd_stat(struct fd *fd, struct stat *);  void fd_incref(struct fd *fd);  // ide.c @@ -115,6 +117,7 @@ void iunlock(struct inode *ip);  void idecref(struct inode *ip);  void iput(struct inode *ip);  struct inode * namei(char *path, uint *); +void stati(struct inode *ip, struct stat *st);  int readi(struct inode *ip, char *xdst, uint off, uint n);  int writei(struct inode *ip, char *addr, uint off, uint n);  struct inode *mknod(char *, short, short, short); @@ -1,4 +1,5 @@  #include "types.h" +#include "stat.h"  #include "param.h"  #include "x86.h"  #include "mmu.h" @@ -121,6 +122,18 @@ fd_close(struct fd *fd)    release(&fd_table_lock);  } +int +fd_stat(struct fd *fd, struct stat *st) +{ +  if(fd->type == FD_FILE){ +    ilock(fd->ip); +    stati(fd->ip, st); +    iunlock(fd->ip); +    return 0; +  } else +    return -1; +} +  void  fd_incref(struct fd *fd)  { @@ -1,4 +1,5 @@  #include "types.h" +#include "stat.h"  #include "param.h"  #include "x86.h"  #include "mmu.h" @@ -270,6 +271,16 @@ bmap(struct inode *ip, uint bn)  #define min(a, b) ((a) < (b) ? (a) : (b)) +void +stati(struct inode *ip, struct stat *st) +{ +  st->st_dev = ip->dev; +  st->st_ino = ip->inum; +  st->st_type = ip->type; +  st->st_nlink = ip->nlink; +  st->st_size = ip->size; +} +  int  readi(struct inode *ip, char *dst, uint off, uint n)  { @@ -0,0 +1,43 @@ +#include "types.h" +#include "stat.h" +#include "user.h" +#include "fs.h" + +char buf[512]; +struct stat stat; +struct dirent dirent; + +int +main(int argc, char *argv[]) +{ +  int fd; +  uint off; + +  if(argc > 1){ +    puts("Usage: ls\n"); +    exit(); +  } + +  fd = open(".", 0); +  if(fd < 0){ +    printf(2, "ls: cannot open .\n"); +    exit(); +  } +  if (fstat(fd, &stat) < 0) { +    printf(2, "ls: cannot open .\n"); +    exit(); +  } +  if (stat.st_type != T_DIR) { +    printf(2, "ls: . is not a dir\n"); +  } +  for(off = 0; off < stat.st_size; off += sizeof(struct dirent)) { +    if (read(fd, &dirent, sizeof(struct dirent)) != sizeof(struct dirent)) { +      printf(2, "ls: read error\n"); +      exit(); +    } +    printf(1, "%s\n", dirent.name); +  } +  close(fd); + +  exit(); +} @@ -0,0 +1,7 @@ +struct stat { +  int st_dev; +  uint st_ino; +  short st_type; +  short st_nlink; +  uint st_size; +}; @@ -1,4 +1,5 @@  #include "types.h" +#include "stat.h"  #include "param.h"  #include "mmu.h"  #include "proc.h" @@ -334,6 +335,28 @@ sys_unlink(void)    return r;  } + +int +sys_fstat(void) +{ +  struct proc *cp = curproc[cpu()]; +  uint fd, addr; +  int r; +   +  if(fetcharg(0, &fd) < 0) +    return -1; +  if(fetcharg(1, &addr) < 0) +    return -1; +  if(fd < 0 || fd >= NOFILE) +    return -1; +  if(cp->fds[fd] == 0) +    return -1; +  if(addr + sizeof(struct stat) > cp->sz) +    return -1; +  r = fd_stat (cp->fds[fd], (struct stat *)(cp->mem + addr)); +  return r; +} +  int  sys_exec(void)  { @@ -570,6 +593,9 @@ syscall(void)    case SYS_unlink:      ret = sys_unlink();      break; +  case SYS_fstat: +    ret = sys_fstat(); +    break;    default:      cprintf("unknown sys call %d\n", num);      // XXX fault @@ -14,4 +14,5 @@  #define SYS_open 14  #define SYS_mknod 15  #define SYS_unlink 16 +#define SYS_fstat 17 @@ -14,7 +14,7 @@ int exec(char *, char **);  int open(char *, int);  int mknod (char*,short,short,short);  int unlink (char*); - +int fstat (int fd, struct stat *stat);  int puts(char*);  char* strcpy(char*, char*);  void printf(int fd, char *fmt, ...); @@ -1,5 +1,6 @@ -#include "user.h"  #include "types.h" +#include "stat.h" +#include "user.h"  #include "fs.h"  #include "fcntl.h" @@ -23,4 +23,5 @@ STUB(cons_puts)  STUB(exec)  STUB(open)  STUB(mknod) -STUB(unlink)	 +STUB(unlink) +STUB(fstat) | 
