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; }
}
}
+ 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
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;
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; }
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); }
}