]> Devi Nivas Git - cs3210-lab1.git/commitdiff
exec arguments
authorrtm <rtm>
Fri, 28 Jul 2006 22:33:07 +0000 (22:33 +0000)
committerrtm <rtm>
Fri, 28 Jul 2006 22:33:07 +0000 (22:33 +0000)
Makefile
Notes
echo.c [new file with mode: 0644]
mkfs.c
syscall.c
userfs.c
usertests.c

index d45bc6fc92bb54314c5bedd596b60cd617a6c5cb..d405284ad975f657b6c23fde45a235a8c74a71d6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -66,6 +66,10 @@ usertests : usertests.o $(ULIB)
        $(LD) -N -e main -Ttext 0 -o usertests usertests.o $(ULIB)
        $(OBJDUMP) -S usertests > usertests.asm
 
+echo : echo.o $(ULIB)
+       $(LD) -N -e main -Ttext 0 -o echo echo.o $(ULIB)
+       $(OBJDUMP) -S echo > echo.asm
+
 userfs : userfs.o $(ULIB)
        $(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB)
        $(OBJDUMP) -S userfs > userfs.asm
@@ -73,12 +77,12 @@ userfs : userfs.o $(ULIB)
 mkfs : mkfs.c fs.h
        cc -o mkfs mkfs.c
 
-fs.img : mkfs usertests
-       ./mkfs fs.img usertests
+fs.img : mkfs usertests echo
+       ./mkfs fs.img usertests echo
 
 -include *.d
 
 clean : 
        rm -f *.o *.d *.asm vectors.S parport.out \
                bootblock kernel xv6.img user1 userfs usertests \
-               fs.img mkfs
+               fs.img mkfs echo
diff --git a/Notes b/Notes
index f0955b8e5a718629bacbb1041cef6d7ce13881d0..22658fcd68912fc5e2d97733ee4e7d6cba87bc56 100644 (file)
--- a/Notes
+++ b/Notes
@@ -161,3 +161,5 @@ need to lock bufs in bio between bread and brelse
 test 14-character file names
 and file arguments longer than 14
 and directories longer than one sector
+
+kalloc() can return 0; do callers handle this right?
diff --git a/echo.c b/echo.c
new file mode 100644 (file)
index 0000000..89e19a9
--- /dev/null
+++ b/echo.c
@@ -0,0 +1,14 @@
+#include "user.h"
+
+int
+main(int argc, char *argv[])
+{
+  int i;
+
+  for(i = 0; i < argc; i++){
+    puts(argv[i]);
+    puts(" ");
+  }
+  puts("\n");
+  exit();
+}
diff --git a/mkfs.c b/mkfs.c
index ae66dfd343a253e6c1b5f8018419e41f53854506..1022adfadd32f4d47e5093c96ce0274b49f45345 100644 (file)
--- a/mkfs.c
+++ b/mkfs.c
@@ -144,11 +144,6 @@ winode(uint inum, struct dinode *ip)
   dip = ((struct dinode *) buf) + (inum % IPB);
   *dip = *ip;
   wsect(bn, buf);
-  printf("wi %d size %d addrs %d %d...\n",
-         inum,
-         xint(dip->size),
-         xint(dip->addrs[0]),
-         xint(dip->addrs[1]));
 }
 
 void
index a8557746e4e8848e383b221555b07437c49030b1..ab9dd170cfcd98adf937e87bef632626e2dbe181 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -58,17 +58,20 @@ fetcharg(int argno, void *ip)
   return fetchint(curproc[cpu()], esp + 4 + 4*argno, ip);
 }
 
-// check that an entire string is valid in user space
+// check that an entire string is valid in user space.
+// returns the length, not including null, or -1.
 int
 checkstring(uint s)
 {
   char c;
+  int len = 0;
 
   while(1){
     if(fetchbyte(curproc[cpu()], s, &c) < 0)
       return -1;
     if(c == '\0')
-      return 0;
+      return len;
+    len++;
     s++;
   }
 }
@@ -244,14 +247,17 @@ int
 sys_exec(void)
 {
   struct proc *cp = curproc[cpu()];
-  uint arg0, sz;
-  int i;
+  uint arg0, arg1, sz=0, ap, sp, p1, p2;
+  int i, nargs, argbytes, len;
   struct inode *ip;
   struct elfhdr elf;
   struct proghdr ph;
+  char *mem = 0;
 
   if(fetcharg(0, &arg0) < 0)
     return -1;
+  if(fetcharg(1, &arg1) < 0)
+    return -1;
   if(checkstring(arg0) < 0)
     return -1;
   ip = namei(cp->mem + arg0);
@@ -278,14 +284,62 @@ sys_exec(void)
   sz += 4096 - (sz % 4096);
   sz += 4096;
 
+  mem = kalloc(sz);
+  if(mem == 0)
+    goto bad;
+  memset(mem, 0, sz);
+
+  // arg1 is a pointer to an array of pointers to string.
+  nargs = 0;
+  argbytes = 0;
+  for(i = 0; ; i++){
+    if(fetchint(cp, arg1 + 4*i, &ap) < 0)
+      goto bad;
+    if(ap == 0)
+      break;
+    len = checkstring(ap);
+    if(len < 0)
+      goto bad;
+    nargs++;
+    argbytes += len + 1;
+  }
+
+  // argn\0
+  // ...
+  // arg0\0
+  // 0
+  // ptr to argn
+  // ...
+  // 12: ptr to arg0
+  //  8: argv (points to ptr to arg0)
+  //  4: argc
+  //  0: fake return pc
+  sp = sz - argbytes - (nargs+1)*4 - 4 - 4 - 4;
+  *(uint*)(mem + sp) = 0xffffffff;
+  *(uint*)(mem + sp + 4) = nargs;
+  *(uint*)(mem + sp + 8) = (uint)(sp + 12);
+
+  p1 = sp + 12;
+  p2 = sp + 12 + (nargs + 1) * 4;
+  for(i = 0; i < nargs; i++){
+    fetchint(cp, arg1 + 4*i, &ap);
+    len = checkstring(ap);
+    memmove(mem + p2, cp->mem + ap, len + 1);
+    *(uint*)(mem + p1) = p2;
+    p1 += 4;
+    p2 += len + 1;
+  }
+  *(uint*)(mem + p1) = 0;
+
   // commit to the new image.
   kfree(cp->mem, cp->sz);
   cp->sz = sz;
-  cp->mem = kalloc(cp->sz);
+  cp->mem = mem;
+  mem = 0;
 
   for(i = 0; i < elf.phnum; i++){
     if(readi(ip, &ph, elf.phoff + i * sizeof(ph), sizeof(ph)) != sizeof(ph))
-      goto bad;
+      goto bad2;
     if(ph.type != ELF_PROG_LOAD)
       continue;
     if(ph.va + ph.memsz > sz)
@@ -298,13 +352,15 @@ sys_exec(void)
   iput(ip);
 
   cp->tf->eip = elf.entry;
-  cp->tf->esp = cp->sz;
+  cp->tf->esp = sp;
   setupsegs(cp);
 
   return 0;
 
  bad:
   cprintf("exec failed early\n");
+  if(mem)
+    kfree(mem, sz);
   iput(ip);
   return -1;
 
index aad93266de4e41365b2b3e464c57b2bdbb1b4414..d3a4923658545c51546338cdc08f61affa5ca51e 100644 (file)
--- a/userfs.c
+++ b/userfs.c
@@ -3,12 +3,13 @@
 // file system tests
 
 char buf[1024];
+char *args[] = { "echo", "hello", "goodbye", 0 };
 
 int
 main(void)
 {
   puts("userfs running\n");
   block();
-  exec("usertests");
+  exec("echo", args);
   return 0;
 }
index 370054b8f96faaea23ae9a7954eba7c0c7106286..cba362ff93aea77f8f14dbcefb7464170c650c46 100644 (file)
@@ -115,7 +115,7 @@ exitwait(void)
 }
 
 int
-main(void)
+main(int argc, char *argv[])
 {
   puts("usertests starting\n");