make Runtime._syscall() protected so it can be overridden from outside the package
[nestedvm.git] / src / org / ibex / nestedvm / UnixRuntime.java
index 0291ab8..5adcba0 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
-// Licensed under the Apache Public Source License 2.0 ("the License").
+// Licensed under the Apache License 2.0 ("the License").
 // You may not use this file except in compliance with the License.
 
 package org.ibex.nestedvm;
 // You may not use this file except in compliance with the License.
 
 package org.ibex.nestedvm;
@@ -119,7 +119,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
         }
     }
     
         }
     }
     
-    int _syscall(int syscall, int a, int b, int c, int d, int e, int f) throws ErrnoException, FaultException {
+    protected int _syscall(int syscall, int a, int b, int c, int d, int e, int f) throws ErrnoException, FaultException {
         switch(syscall) {
             case SYS_kill: return sys_kill(a,b);
             case SYS_fork: return sys_fork();
         switch(syscall) {
             case SYS_kill: return sys_kill(a,b);
             case SYS_fork: return sys_fork();
@@ -164,7 +164,10 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
     }
     
     FD _open(String path, int flags, int mode) throws ErrnoException {
     }
     
     FD _open(String path, int flags, int mode) throws ErrnoException {
-        return gs.open(this,normalizePath(path),flags,mode);
+        path = normalizePath(path);
+        FD fd = gs.open(this,path,flags,mode);
+        if (fd != null && path != null) fd.setNormalizedPath(path);
+        return fd;
     }
     
     private int sys_getppid() {
     }
     
     private int sys_getppid() {
@@ -192,7 +195,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
     
     private int sys_access(int cstring, int mode) throws ErrnoException, ReadFaultException {
         // FEATURE: sys_access
     
     private int sys_access(int cstring, int mode) throws ErrnoException, ReadFaultException {
         // FEATURE: sys_access
-        return gs.stat(this,cstring(cstring)) == null ? -ENOENT : 0;
+        return gs.stat(this,normalizePath(cstring(cstring))) == null ? -ENOENT : 0;
     }
     
     private int sys_realpath(int inAddr, int outAddr) throws FaultException {
     }
     
     private int sys_realpath(int inAddr, int outAddr) throws FaultException {
@@ -560,7 +563,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
         return 0;   
     }
     
         return 0;   
     }
     
-    static class Pipe {
+    public static class Pipe {
         private final byte[] pipebuf = new byte[PIPE_BUF*4];
         private int readPos;
         private int writePos;
         private final byte[] pipebuf = new byte[PIPE_BUF*4];
         private int readPos;
         private int writePos;
@@ -703,7 +706,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
         return n;
     }
 
         return n;
     }
 
-    void _closedFD(FD fd) {
+    void _preCloseFD(FD fd) {
         // release all fcntl locks on this file
         Seekable s = fd.seekable();
         if (s == null) return;
         // release all fcntl locks on this file
         Seekable s = fd.seekable();
         if (s == null) return;
@@ -720,6 +723,13 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
         } catch (IOException e) { throw new RuntimeException(e); }
     }
 
         } catch (IOException e) { throw new RuntimeException(e); }
     }
 
+    void _postCloseFD(FD fd) {
+        if (fd.isMarkedForDeleteOnClose()) {
+            try { gs.unlink(this, fd.getNormalizedPath()); }
+            catch (Throwable t) {}
+        }
+    }
+
     /** Implements the F_GETLK and F_SETLK cases of fcntl syscall.
      *  If l_start = 0 and l_len = 0 the lock refers to the entire file.
      *  Uses GlobalState to ensure locking across processes in the same JVM.
     /** Implements the F_GETLK and F_SETLK cases of fcntl syscall.
      *  If l_start = 0 and l_len = 0 the lock refers to the entire file.
      *  Uses GlobalState to ensure locking across processes in the same JVM.
@@ -1352,6 +1362,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
                 
                 addMount("/dev",new DevFS());
                 addMount("/resource",new ResourceFS());
                 
                 addMount("/dev",new DevFS());
                 addMount("/resource",new ResourceFS());
+                addMount("/cygdrive",new CygdriveFS());
             }
         }
         
             }
         }
         
@@ -1591,7 +1602,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
         protected File root;
         public File getRoot() { return root; }
         
         protected File root;
         public File getRoot() { return root; }
         
-        private File hostFile(String path) {
+        protected File hostFile(String path) {
             char sep = File.separatorChar;
             if(sep != '/') {
                 char buf[] = path.toCharArray();
             char sep = File.separatorChar;
             if(sep != '/') {
                 char buf[] = path.toCharArray();
@@ -1617,7 +1628,21 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
             File f = hostFile(path);
             if(r.sm != null && !r.sm.allowUnlink(f)) throw new ErrnoException(EPERM);
             if(!f.exists()) throw new ErrnoException(ENOENT);
             File f = hostFile(path);
             if(r.sm != null && !r.sm.allowUnlink(f)) throw new ErrnoException(EPERM);
             if(!f.exists()) throw new ErrnoException(ENOENT);
-            if(!f.delete()) throw new ErrnoException(EPERM);
+            if(!f.delete()) {
+                // Can't delete file immediately, so mark for
+                // delete on close all matching FDs
+                boolean marked = false;
+                for(int i=0;i<OPEN_MAX;i++) {
+                    if(r.fds[i] != null) {
+                        String fdpath = r.fds[i].getNormalizedPath();
+                        if(fdpath != null && fdpath.equals(path)) {
+                            r.fds[i].markDeleteOnClose();
+                            marked = true;
+                        }
+                    }
+                }
+                if(!marked) throw new ErrnoException(EPERM);
+            }
         }
         
         public FStat stat(UnixRuntime r, String path) throws ErrnoException {
         }
         
         public FStat stat(UnixRuntime r, String path) throws ErrnoException {
@@ -1663,6 +1688,23 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
             public int myDev() { return devno; } 
         }
     }
             public int myDev() { return devno; } 
         }
     }
+
+    /* Implements the Cygwin notation for accessing MS Windows drive letters
+     * in a unix path. The path /cygdrive/c/myfile is converted to C:\file.
+     * As there is no POSIX standard for this, little checking is done. */
+    public static class CygdriveFS extends HostFS {
+        protected File hostFile(String path) {
+            final char drive = path.charAt(0);
+
+            if (drive < 'a' || drive > 'z' || path.charAt(1) != '/')
+                return null;
+
+            path = drive + ":" + path.substring(1).replace('/', '\\');
+            return new File(path);
+        }
+
+        public CygdriveFS() { super("/"); }
+    }
     
     private static void putInt(byte[] buf, int off, int n) {
         buf[off+0] = (byte)((n>>>24)&0xff);
     
     private static void putInt(byte[] buf, int off, int n) {
         buf[off+0] = (byte)((n>>>24)&0xff);
@@ -1769,7 +1811,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable {
             if(path.startsWith("fd/")) {
                 int n;
                 try {
             if(path.startsWith("fd/")) {
                 int n;
                 try {
-                    n = Integer.parseInt(path.substring(4));
+                    n = Integer.parseInt(path.substring(3));
                 } catch(NumberFormatException e) {
                     return null;
                 }
                 } catch(NumberFormatException e) {
                     return null;
                 }