X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FUnixRuntime.java;h=5eb9178ce34e085a1e11ac34691a29ab56cf2013;hp=8aa5dc77ce9feaf9228804dbb81c2e51b059946f;hb=98f786ce8ee1fcd9568d1c367160851d32e1c786;hpb=ad692a248f2ed9412db5b313b85fd8365488017f diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 8aa5dc7..5eb9178 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -4,14 +4,10 @@ import org.ibex.nestedvm.util.*; import java.io.*; import java.util.*; -// FIXME: Fix readdir in support_aux.c // FIXME: Make plain old "mips-unknown-elf-gcc -o foo foo.c" work (modify spec file or whatever) // FEATURE: Remove System.{out,err}.printlns and throw Errors where applicable -// FIXME: BusyBox's ASH doesn't like \r\n at the end of lines -// is ash just broken or are many apps like this? if so workaround in nestedvm - public abstract class UnixRuntime extends Runtime implements Cloneable { /** The pid of this "process" */ private int pid; @@ -112,6 +108,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { case SYS_getcwd: return sys_getcwd(a,b); case SYS_chdir: return sys_chdir(a); case SYS_exec: return sys_exec(a,b,c); + case SYS_getdents: return sys_getdents(a,b,c,d); default: return super._syscall(syscall,a,b,c,d); } @@ -407,7 +404,6 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return 0; } - private int sys_getcwd(int addr, int size) throws FaultException, ErrnoException { byte[] b = getBytes(cwd); if(size == 0) return -EINVAL; @@ -427,6 +423,16 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return 0; } + private int sys_getdents(int fdn, int addr, int count, int seekptr) throws FaultException, ErrnoException { + count = Math.min(count,MAX_CHUNK); + if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; + if(fds[fdn] == null) return -EBADFD; + byte[] buf = byteBuf(count); + int n = fds[fdn].getdents(buf,0,count); + copyout(buf,addr,n); + return n; + } + // FEATURE: Run through the fork/wait stuff one more time public static class GlobalState { protected static final int OPEN = 1; @@ -437,7 +443,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { final UnixRuntime[] tasks; int nextPID = 1; - private final MP[][] mps = new MP[128][]; + private MP[] mps = new MP[0]; private FS root; public GlobalState() { this(255); } @@ -445,7 +451,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public GlobalState(int maxProcs, boolean defaultMounts) { tasks = new UnixRuntime[maxProcs+1]; if(defaultMounts) { - root = new HostFS(); + addMount("/",new HostFS()); addMount("/dev",new DevFS()); } } @@ -464,56 +470,70 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { if(!path.startsWith("/")) throw new IllegalArgumentException("Mount point doesn't start with a /"); if(path.equals("/")) return root; path = path.substring(1); - int f = path.charAt(0) & 0x7f; - for(int i=0;mps[f] != null && i < mps[f].length;i++) - if(mps[f][i].path.equals(path)) return mps[f][i].fs; + for(int i=0;i>>24)&0xff); + buf[off+1] = (byte)((n>>>16)&0xff); + buf[off+2] = (byte)((n>>> 8)&0xff); + buf[off+3] = (byte)((n>>> 0)&0xff); + } + + public static abstract class DirFD extends FD { + private int pos = -2; + + protected abstract int size(); + protected abstract String name(int n); + protected abstract int inode(int n); + protected abstract int myDev(); + protected int parentInode() { return -1; } + protected int myInode() { return -1; } + + public int getdents(byte[] buf, int off, int len) { + int ooff = off; + int ino; + int reclen; + OUTER: for(;len > 0 && pos < size();pos++){ + switch(pos) { + case -2: + case -1: + ino = pos == -1 ? parentInode() : myInode(); + if(ino == -1) continue; + reclen = 9 + (pos == -1 ? 2 : 1); + if(reclen > len) break OUTER; + buf[off+8] = '.'; + if(pos == -1) buf[off+9] = '.'; + break; + default: { + String f = name(pos); + byte[] fb = getBytes(f); + reclen = fb.length + 9; + if(reclen > len) break OUTER; + ino = inode(pos); + System.arraycopy(fb,0,buf,off+8,fb.length); + } + } + buf[off+reclen-1] = 0; // null terminate + reclen = (reclen + 3) & ~3; // add padding + putInt(buf,off,reclen); + putInt(buf,off+4,ino); + off += reclen; + len -= reclen; + } + return off-ooff; + } + + protected FStat _fstat() { + return new FStat() { + public int type() { return S_IFDIR; } + public int inode() { return myInode(); } + public int dev() { return myDev(); } + }; + } } public static class DevFS extends FS { - private static class DevFStat extends FStat { - public int dev() { return 1; } + private static final int ROOT_INODE = 1; + private static final int NULL_INODE = 2; + private static final int ZERO_INODE = 3; + private static final int FD_INODE = 4; + private static final int FD_INODES = 32; + + private class DevFStat extends FStat { + public int dev() { return devno; } public int mode() { return 0666; } public int type() { return S_IFCHR; } public int nlink() { return 1; } } - private static FD devZeroFD = new FD() { + + private abstract class DevDirFD extends DirFD { + public int myDev() { return devno; } + } + + private FD devZeroFD = new FD() { public boolean readable() { return true; } public boolean writable() { return true; } public int read(byte[] a, int off, int length) { Arrays.fill(a,off,off+length,(byte)0); return length; } public int write(byte[] a, int off, int length) { return length; } public int seek(int n, int whence) { return 0; } - public FStat _fstat() { return new DevFStat(); } + public FStat _fstat() { return new DevFStat(){ public int inode() { return ZERO_INODE; } }; } }; - private static FD devNullFD = new FD() { + private FD devNullFD = new FD() { public boolean readable() { return true; } public boolean writable() { return true; } public int read(byte[] a, int off, int length) { return 0; } public int write(byte[] a, int off, int length) { return length; } public int seek(int n, int whence) { return 0; } - public FStat _fstat() { return new DevFStat(); } + public FStat _fstat() { return new DevFStat(){ public int inode() { return NULL_INODE; } }; } }; public FD open(UnixRuntime r, String path, int mode, int flags) throws ErrnoException { @@ -816,15 +910,42 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } if(path.equals("fd")) { int count=0; - for(int i=0;i