got a hotel
[nestedvm.git] / src / org / ibex / nestedvm / Runtime.java
index c501d0d..c2941f0 100644 (file)
@@ -2,13 +2,16 @@
 // Based on org.xwt.imp.MIPS by Adam Megacz
 // Portions Copyright 2003 Adam Megacz
 
+// FEATURE: Add a patch to gcc that enabled -Wall -Werror by default
+
 package org.ibex.nestedvm;
 
 import org.ibex.nestedvm.util.*;
 import java.io.*;
-import java.util.Arrays;
 
 public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
+    public static final String VERSION = "1.0";
+    
     /** True to write useful diagnostic information to stderr when things go wrong */
     final static boolean STDERR_DIAG = true;
     
@@ -45,10 +48,10 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
     /** When the process started */
     private long startTime;
     
-    /**  Text/Data loaded in memory  */
-    public final static int STOPPED = 0;
     /** Program is executing instructions */
-    public final static int RUNNING = 1;
+    public final static int RUNNING = 0; // Horrible things will happen if this isn't 0
+    /**  Text/Data loaded in memory  */
+    public final static int STOPPED = 1;
     /** Prgram has been started but is paused */
     public final static int PAUSED = 2;
     /** Program is executing a callJava() method */
@@ -357,7 +360,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
                 if(page == null) throw new WriteFaultException(a<<2);
                 int index = a&pageWordMask;
                 int n = min(c,pageWords-index);
-                Arrays.fill(page,index,index+n,fourBytes);
+                /* Arrays.fill(page,index,index+n,fourBytes);*/
+                for(int i=index;i<index+n;i++) page[i] = fourBytes;
                 a += n; c -= n;
             }
             addr = a<<2; count&=3;
@@ -719,8 +723,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
         
         if((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT)) {
             try {
-                // NOTE: createNewFile is a Java2 function
-                if(!f.createNewFile()) throw new ErrnoException(EEXIST);
+                if(Platform.atomicCreateFile(f)) throw new ErrnoException(EEXIST);
             } catch(IOException e) {
                 throw new ErrnoException(EIO);
             }
@@ -730,10 +733,9 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
             return hostFSDirFD(f,data);
         }
         
-        // FIXME: Truncate
         final Seekable.File sf;
         try {
-            sf = new Seekable.File(f,write);
+            sf = new Seekable.File(f,write,(flags & O_TRUNC) != 0);
         } catch(FileNotFoundException e) {
             if(e.getMessage() != null && e.getMessage().indexOf("Permission denied") >= 0) throw new ErrnoException(EACCES);
             return null;
@@ -752,8 +754,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
     
     /** The open syscall */
     private int sys_open(int addr, int flags, int mode) throws ErrnoException, FaultException {
+        String name = cstring(addr);
+        
+        // HACK: TeX, or GPC, or something really sucks
+        if(name.length() == 1024 && getClass().getName().equals("tests.TeX")) name = name.trim();
+        
         flags &= ~O_NOCTTY; // this is meaningless under nestedvm
-        FD fd = _open(cstring(addr),flags,mode);
+        FD fd = _open(name,flags,mode);
         if(fd == null) return -ENOENT;
         int fdn = addFD(fd);
         if(fdn == -1) { fd.close(); return -ENFILE; }
@@ -803,12 +810,11 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
     }
     
     /** The stat/fstat syscall helper */
-    // FIXME: Populate uid/gid/nlink
     int stat(FStat fs, int addr) throws FaultException {
         memWrite(addr+0,(fs.dev()<<16)|(fs.inode()&0xffff)); // st_dev (top 16), // st_ino (bottom 16)
         memWrite(addr+4,((fs.type()&0xf000))|(fs.mode()&0xfff)); // st_mode
-        memWrite(addr+8,1<<16); // st_nlink (top 16) // st_uid (bottom 16)
-        memWrite(addr+12,0); // st_gid (top 16) // st_rdev (bottom 16)
+        memWrite(addr+8,fs.nlink()<<16|fs.uid()&0xffff); // st_nlink (top 16) // st_uid (bottom 16)
+        memWrite(addr+12,fs.gid()<<16|0); // st_gid (top 16) // st_rdev (bottom 16)
         memWrite(addr+16,fs.size()); // st_size
         memWrite(addr+20,fs.atime()); // st_atime
         // memWrite(addr+24,0) // st_spare1
@@ -935,7 +941,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
                 ret = callJavaCB.call(a,b,c,d);
             } catch(RuntimeException e) {
                 System.err.println("Error while executing callJavaCB");
-                    e.printStackTrace();
+                e.printStackTrace();
                 ret = 0;
             }
             state = RUNNING;
@@ -977,7 +983,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
                 for(i=arg;i<OPEN_MAX;i++) if(fds[i]==null) break;
                 if(i==OPEN_MAX) return -EMFILE;
                 fds[i] = fd.dup();
-                return 0;
+                return i;
             case F_GETFL:
                 return fd.flags();
             case F_SETFD:
@@ -996,20 +1002,23 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
         <i>syscall</i> should be the contents of V0 and <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> should be 
         the contenst of A0, A1, A2, and A3. The call MAY change the state
         @see Runtime#state state */
-    protected final int syscall(int syscall, int a, int b, int c, int d) {
+    protected final int syscall(int syscall, int a, int b, int c, int d, int e, int f) {
         try {
-            return _syscall(syscall,a,b,c,d);
-        } catch(ErrnoException e) {
-            return -e.errno;
-        } catch(FaultException e) {
+            int n = _syscall(syscall,a,b,c,d,e,f);
+            //if(n < 0) System.err.println("syscall: " + syscall + " returned " + n);
+            return n;
+        } catch(ErrnoException ex) {
+            //ex.printStackTrace();
+            return -ex.errno;
+        } catch(FaultException ex) {
             return -EFAULT;
-        } catch(RuntimeException e) {
-            e.printStackTrace();
+        } catch(RuntimeException ex) {
+            ex.printStackTrace();
             throw new Error("Internal Error in _syscall()");
         }
     }
     
-    int _syscall(int syscall, int a, int b, int c, int d) throws ErrnoException, FaultException {
+    int _syscall(int syscall, int a, int b, int c, int d, int e, int f) throws ErrnoException, FaultException {
         switch(syscall) {
             case SYS_null: return 0;
             case SYS_exit: return sys_exit(a);
@@ -1194,8 +1203,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
         }
         
         public void _close() {
-            try {is.close(); } catch(IOException e) { /*ignore*/ }
-            try {os.close(); } catch(IOException e) { /*ignore*/ }
+            if(is != null) try { is.close(); } catch(IOException e) { /*ignore*/ }
+            if(os != null) try { os.close(); } catch(IOException e) { /*ignore*/ }
         }
         
         public int read(byte[] a, int off, int length) throws ErrnoException {
@@ -1226,10 +1235,10 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
         public TerminalFD(OutputStream os) { this(null,os); }
         public TerminalFD(InputStream is, OutputStream os) { super(is,os); }
         public void _close() { /* noop */ }
-        public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } }; }
+        public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } public int mode() { return 0600; } }; }
     }
     
-    // FEATURE: TextInputStream: This is pretty inefficient but it is only used for reading from the console on win32
+    // This is pretty inefficient but it is only used for reading from the console on win32
     static class TextInputStream extends InputStream {
         private int pushedBack = -1;
         private final InputStream parent;
@@ -1419,6 +1428,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
         }
     }
     
+    static byte[] getNullTerminatedBytes(String s) {
+        byte[] buf1 = getBytes(s);
+        byte[] buf2 = new byte[buf1.length+1];
+        System.arraycopy(buf1,0,buf2,0,buf1.length);
+        return buf2;
+    }
+    
     final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
     final static int min(int a, int b) { return a < b ? a : b; }
     final static int max(int a, int b) { return a > b ? a : b; }