X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntime.java;h=2a91e3613ebda8733909fef05888a0aa83b9ce50;hp=44505c121bb38181cba0d1d24c4426ea21a544de;hb=b11e7c6c29f2b5f7b0828bf93eb741c4a30ec411;hpb=1b398f9945d32b9d63d7fc64c9cf7a6af332d290 diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java index 44505c1..2a91e36 100644 --- a/src/org/ibex/nestedvm/Runtime.java +++ b/src/org/ibex/nestedvm/Runtime.java @@ -1,5 +1,5 @@ // 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. // Copyright 2003 Brian Alliet @@ -76,10 +76,6 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { /** Table containing all open file descriptors. (Entries are null if the fd is not in use */ FD[] fds; // package-private for UnixRuntime boolean closeOnExec[]; - - /** Table of all current file locks held by this process. */ - Seekable.Lock[] locks; - public static final int LOCK_MAX = 8; /** Pointer to a SecurityManager for this process */ SecurityManager sm; @@ -126,7 +122,6 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { r.startTime = 0; r.fds = new FD[OPEN_MAX]; for(int i=0;ifdn and removes it from the file descriptor table */ public final boolean closeFD(int fdn) { if(state == EXITED || state == EXECED) throw new IllegalStateException("closeFD called in inappropriate state"); if(fdn < 0 || fdn >= OPEN_MAX) return false; if(fds[fdn] == null) return false; - - // release all fcntl locks on this file - Seekable s = fds[fdn].seekable(); - if (s != null) { - try { - for (int i=0; i < LOCK_MAX; i++) { - if (locks[i] != null && s.equals(locks[i].seekable())) { - locks[i].release(); - locks[i] = null; - } - } - } catch (IOException e) { throw new RuntimeException(e); } - } - + _preCloseFD(fds[fdn]); fds[fdn].close(); + _postCloseFD(fds[fdn]); fds[fdn] = null; return true; } @@ -781,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; } @@ -1031,7 +1017,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return 0; } - private int sys_fcntl(int fdn, int cmd, int arg) throws FaultException { + final int sys_fcntl(int fdn, int cmd, int arg) throws FaultException { int i; if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; @@ -1054,123 +1040,30 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return closeOnExec[fdn] ? 1 : 0; case F_GETLK: case F_SETLK: - try { - return sys_fcntl_lock(fd, cmd, arg); - } catch (IOException e) { throw new RuntimeException(e);} + if(STDERR_DIAG) System.err.println("WARNING: file locking requires UnixRuntime"); + return -ENOSYS; default: if(STDERR_DIAG) System.err.println("WARNING: Unknown fcntl command: " + cmd); return -ENOSYS; } } - /** 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. - struct flock { - short l_type; // lock type: F_UNLCK, F_RDLCK, F_WRLCK - short l_whence; // type of l_start: SEEK_SET, SEEK_CUR, SEEK_END - long l_start; // starting offset, bytes - long l_len; // len = 0 means until EOF - short l_pid; // lock owner - short l_xxx; // padding - }; - */ - private int sys_fcntl_lock(FD fd, int cmd, int arg) - throws FaultException, IOException { - if (arg == 0) { System.out.println("BAD ARG"); return -EINVAL; } - int word = memRead(arg); - int l_start = memRead(arg+4); - int l_len = memRead(arg+8); - int l_type = word>>16; - int l_whence = word&0x00ff; + 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; - switch (l_whence) { - case SEEK_SET: break; - case SEEK_CUR: l_start += s.pos(); break; - case SEEK_END: l_start += s.length(); break; - default: return -1; - } - - if (cmd != F_GETLK && cmd != F_SETLK) return -EINVAL; - - if (cmd == F_GETLK) { - // Check if an l_type lock can be aquired. The only way to - // do this within the Java API is to try and create a lock. - Seekable.Lock lock = s.lock(l_start, l_len, l_type == F_RDLCK); - - if (lock != null) { - // no lock exists - memWrite(arg, SEEK_SET|(F_UNLCK<<16)); - lock.release(); - } - - return 0; - } - - // now processing F_SETLK - if (cmd != F_SETLK) return -EINVAL; - - if (l_type == F_UNLCK) { - // release all locks that fall within the boundaries given - for (int i=0; i < LOCK_MAX; i++) { - if (locks[i] == null || !s.equals(locks[i].seekable())) - continue; - - int pos = (int)locks[i].position(); - if (pos < l_start) continue; - if (l_start != 0 && l_len != 0) // start/len 0 means unlock all - if (pos + locks[i].size() > l_start + l_len) - continue; - - locks[i].release(); - locks[i] = null; - } - return 0; - - } else if (l_type == F_RDLCK || l_type == F_WRLCK) { - // first see if a lock already exists - for (int i=0; i < LOCK_MAX; i++) { - if (locks[i] == null || !s.equals(locks[i].seekable())) - continue; - int pos = (int)locks[i].position(); - int size = (int)locks[i].size(); - if (l_start < pos && pos + size < l_start + l_len) { - // found a lock contained in the new requested lock - locks[i].release(); - locks[i] = null; - - } else if (l_start >= pos && pos + size >= l_start + l_len) { - // found a lock that contains the requested lock - if (locks[i].isShared() == (l_type == F_RDLCK)) { - memWrite(arg+4, pos); - memWrite(arg+8, size); - return 0; - } else { - locks[i].release(); - locks[i] = null; - } - } - } - - // create the lock - Seekable.Lock lock = s.lock(l_start, l_len, l_type == F_RDLCK); - if (lock == null) return -EAGAIN; - - int i; - for (i=0; i < LOCK_MAX; i++) - if (locks[i] == null) break; - if (i == LOCK_MAX) return -ENOLCK; - locks[i] = lock; + try { + s.sync(); return 0; - - } else { - return -EINVAL; + } catch (IOException e) { + return -EIO; } } - /** The syscall dispatcher. The should be called by subclasses when the syscall instruction is invoked. syscall should be the contents of V0 and a, b, c, and d should be @@ -1220,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; @@ -1315,6 +1209,14 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { /** File Descriptor class */ public static abstract class FD { private int refCount = 1; + private String normalizedPath = null; + private boolean deleteOnClose = false; + + public void setNormalizedPath(String path) { normalizedPath = path; } + public String getNormalizedPath() { return normalizedPath; } + + public void markDeleteOnClose() { deleteOnClose = true; } + public boolean isMarkedForDeleteOnClose() { return deleteOnClose; } /** Read some bytes. Should return the number of bytes read, 0 on EOF, or throw an IOException on error */ public int read(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); } @@ -1519,10 +1421,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; } @@ -1537,7 +1442,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); } }