avoid file length caching in fstat (from Joe Wilson)
[nestedvm.git] / src / org / ibex / nestedvm / Runtime.java
index f8a1579..8e6b5f0 100644 (file)
@@ -767,10 +767,10 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
             return null;
         } catch(IOException e) { throw new ErrnoException(EIO); }
         
-        return new SeekableFD(sf,flags) { protected FStat _fstat() { return hostFStat(f,data); } };
+        return new SeekableFD(sf,flags) { protected FStat _fstat() { return hostFStat(f,sf,data); } };
     }
     
-    FStat hostFStat(File f, Object data) { return new HostFStat(f); }
+    FStat hostFStat(File f, Seekable.File sf, Object data) { return new HostFStat(f,sf); }
     
     FD hostFSDirFD(File f, Object data) { return null; }
     
@@ -1048,6 +1048,22 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
         }
     }
 
+    final int fsync(int fdn) {
+        if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+        if(fds[fdn] == null) return -EBADFD;
+        FD fd = fds[fdn];
+
+        Seekable s = fd.seekable();
+        if (s == null) return -EINVAL;
+
+        try {
+            s.sync();
+            return 0;
+        } catch (IOException e) {
+            return -EIO;
+        }
+    }
+
     /** The syscall dispatcher.
         The should be called by subclasses when the syscall instruction is invoked.
         <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 
@@ -1097,6 +1113,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
             case SYS_getgid: return sys_getgid();
             case SYS_getegid: return sys_getegid();
             
+            case SYS_fsync: return fsync(a);
             case SYS_memcpy: memcpy(a,b,c); return a;
             case SYS_memset: memset(a,b,c); return a;
 
@@ -1396,10 +1413,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
     
     static class HostFStat extends FStat {
         private final File f;
+        private final Seekable.File sf;
         private final boolean executable; 
-        public HostFStat(File f) { this(f,false); }
-        public HostFStat(File f, boolean executable) {
+        public HostFStat(File f, Seekable.File sf) { this(f,sf,false); }
+        public HostFStat(File f, boolean executable) {this(f,null,executable);}
+        public HostFStat(File f, Seekable.File sf, boolean executable) {
             this.f = f;
+            this.sf = sf;
             this.executable = executable;
         }
         public int dev() { return 1; }
@@ -1414,7 +1434,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
             if(f.canWrite()) mode |= 0222;
             return mode;
         }
-        public int size() { return (int) f.length(); }
+        public int size() {
+          try {
+            return sf != null ? (int)sf.length() : (int)f.length();
+          } catch (Exception x) {
+            return (int)f.length();
+          }
+        }
         public int mtime() { return (int)(f.lastModified()/1000); }        
     }