X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FUnixRuntime.java;h=0bed8ed27ef330538112c773149dacc134fec68d;hp=5eb9178ce34e085a1e11ac34691a29ab56cf2013;hb=2db6b04d7557a26e3b9e7440e7968aaec262216f;hpb=98f786ce8ee1fcd9568d1c367160851d32e1c786 diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 5eb9178..0bed8ed 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -4,9 +4,7 @@ import org.ibex.nestedvm.util.*; import java.io.*; import java.util.*; -// 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 +// FEATURE: vfork public abstract class UnixRuntime extends Runtime implements Cloneable { /** The pid of this "process" */ @@ -14,8 +12,12 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private UnixRuntime parent; public final int getPid() { return pid; } - private static final GlobalState defaultGD = new GlobalState(); - private GlobalState gd = defaultGD; + private static final GlobalState defaultGS = new GlobalState(); + private GlobalState gs = defaultGS; + public void setGlobalState(GlobalState gs) { + if(state != STOPPED) throw new IllegalStateException("can't change GlobalState when running"); + this.gs = gs; + } /** proceses' current working directory - absolute path WITHOUT leading slash "" = root, "bin" = /bin "usr/bin" = /usr/bin */ @@ -33,7 +35,9 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { // FEATURE: Do the proper mangling for non-unix hosts String userdir = getSystemProperty("user.dir"); - cwd = userdir != null && userdir.startsWith("/") && File.separatorChar == '/' ? userdir.substring(1) : ""; + cwd = + userdir != null && userdir.startsWith("/") && File.separatorChar == '/' && getSystemProperty("nestedvm.root") == null + ? userdir.substring(1) : ""; } // NOTE: getDisplayName() is a Java2 function @@ -59,16 +63,17 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } String[] createEnv(String[] extra) { - String[] defaults = new String[5]; + String[] defaults = new String[6]; int n=0; if(extra == null) extra = new String[0]; if(!envHas("USER",extra) && getSystemProperty("user.name") != null) defaults[n++] = "USER=" + getSystemProperty("user.name"); - if(!envHas("HOME",extra) && getSystemProperty("user.name") != null) + if(!envHas("HOME",extra) && getSystemProperty("user.home") != null) defaults[n++] = "HOME=" + getSystemProperty("user.home"); if(!envHas("SHELL",extra)) defaults[n++] = "SHELL=/bin/sh"; if(!envHas("TERM",extra)) defaults[n++] = "TERM=vt100"; if(!envHas("TZ",extra)) defaults[n++] = "TZ=" + posixTZ(); + if(!envHas("PATH",extra)) defaults[n++] = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"; String[] env = new String[extra.length+n]; for(int i=0;i= gd.tasks.length)) return -ECHILD; + if(pid !=-1 && (pid <= 0 || pid >= gs.tasks.length)) return -ECHILD; if(children == null) return blocking ? -ECHILD : 0; UnixRuntime done = null; @@ -166,7 +184,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { if(pid == -1) { if(exitedChildren.size() > 0) done = (UnixRuntime)exitedChildren.remove(exitedChildren.size() - 1); } else if(pid > 0) { - UnixRuntime t = gd.tasks[pid]; + UnixRuntime t = gs.tasks[pid]; if(t.parent != this) return -ECHILD; if(t.state == EXITED) { if(!exitedChildren.remove(t)) throw new Error("should never happen"); @@ -174,14 +192,14 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } } else { // process group stuff, EINVAL returned above - throw new Error("should never happen"); + throw new Error("should never happen"); } if(done == null) { if(!blocking) return 0; try { children.wait(); } catch(InterruptedException e) {} - System.err.println("waitpid woke up: " + exitedChildren.size()); + //System.err.println("waitpid woke up: " + exitedChildren.size()); } else { - gd.tasks[done.pid] = null; + gs.tasks[done.pid] = null; break; } } @@ -195,7 +213,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { if(children != null) synchronized(children) { for(Enumeration e = exitedChildren.elements(); e.hasMoreElements(); ) { UnixRuntime child = (UnixRuntime) e.nextElement(); - gd.tasks[child.pid] = null; + gs.tasks[child.pid] = null; } exitedChildren.clear(); for(Enumeration e = activeChildren.elements(); e.hasMoreElements(); ) { @@ -207,13 +225,13 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { UnixRuntime _parent = parent; if(_parent == null) { - gd.tasks[pid] = null; + gs.tasks[pid] = null; } else { synchronized(_parent.children) { if(parent == null) { - gd.tasks[pid] = null; + gs.tasks[pid] = null; } else { - parent.activeChildren.remove(this); + if(!parent.activeChildren.remove(this)) throw new Error("should never happen _exited: pid: " + pid); parent.exitedChildren.add(this); parent.children.notify(); } @@ -222,7 +240,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } protected Object clone() throws CloneNotSupportedException { - UnixRuntime r = (UnixRuntime) super.clone(); + UnixRuntime r = (UnixRuntime) super.clone(); r.pid = 0; r.parent = null; r.children = null; @@ -248,10 +266,10 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { try { r._started(); } catch(ProcessTableFullExn e) { - return -ENOMEM; + return -ENOMEM; } - System.err.println("fork " + pid + " -> " + r.pid + " tasks[" + r.pid + "] = " + gd.tasks[r.pid]); + //System.err.println("fork " + pid + " -> " + r.pid + " tasks[" + r.pid + "] = " + gd.tasks[r.pid]); if(children == null) { children = new Object(); activeChildren = new Vector(); @@ -279,10 +297,10 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public static int runAndExec(UnixRuntime r, String[] argv) { r.start(argv); return executeAndExec(r); } public static int executeAndExec(UnixRuntime r) { - for(;;) { + for(;;) { for(;;) { if(r.execute()) break; - System.err.println("WARNING: Pause requested while executing runAndExec()"); + if(STDERR_DIAG) System.err.println("WARNING: Pause requested while executing runAndExec()"); } if(r.state != EXECED) return r.exitStatus(); r = r.execedRuntime; @@ -290,7 +308,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } private String[] readStringArray(int addr) throws ReadFaultException { - int count = 0; + int count = 0; for(int p=addr;memRead(p) != 0;p+=4) count++; String[] a = new String[count]; for(int i=0,p=addr;i= OPEN_MAX) return -EBADFD; + if(fds[oldd] == null) return -EBADFD; + FD fd = fds[oldd].dup(); + int newd = addFD(fd); + if(newd < 0) { fd.close(); return -ENFILE; } + return newd; + } + private int sys_stat(int cstring, int addr) throws FaultException, ErrnoException { - FStat s = gd.stat(this,normalizePath(cstring(cstring))); + FStat s = gs.stat(this,normalizePath(cstring(cstring))); if(s == null) return -ENOENT; return stat(s,addr); } private int sys_lstat(int cstring, int addr) throws FaultException, ErrnoException { - FStat s = gd.lstat(this,normalizePath(cstring(cstring))); + FStat s = gs.lstat(this,normalizePath(cstring(cstring))); if(s == null) return -ENOENT; return stat(s,addr); } private int sys_mkdir(int cstring, int mode) throws FaultException, ErrnoException { - gd.mkdir(this,normalizePath(cstring(cstring)),mode); + gs.mkdir(this,normalizePath(cstring(cstring)),mode); return 0; } + private int sys_unlink(int cstring) throws FaultException, ErrnoException { + gs.unlink(this,normalizePath(cstring(cstring))); + return 0; + } + private int sys_getcwd(int addr, int size) throws FaultException, ErrnoException { byte[] b = getBytes(cwd); if(size == 0) return -EINVAL; @@ -416,10 +502,10 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private int sys_chdir(int addr) throws ErrnoException, FaultException { String path = normalizePath(cstring(addr)); - System.err.println("Chdir: " + cstring(addr) + " -> " + path + " pwd: " + cwd); - if(gd.stat(this,path).type() != FStat.S_IFDIR) return -ENOTDIR; + //System.err.println("Chdir: " + cstring(addr) + " -> " + path + " pwd: " + cwd); + if(gs.stat(this,path).type() != FStat.S_IFDIR) return -ENOTDIR; cwd = path; - System.err.println("Now: [" + cwd + "]"); + //System.err.println("Now: [" + cwd + "]"); return 0; } @@ -439,6 +525,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { protected static final int STAT = 2; protected static final int LSTAT = 3; protected static final int MKDIR = 4; + protected static final int UNLINK = 5; final UnixRuntime[] tasks; int nextPID = 1; @@ -451,7 +538,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public GlobalState(int maxProcs, boolean defaultMounts) { tasks = new UnixRuntime[maxProcs+1]; if(defaultMounts) { - addMount("/",new HostFS()); + addMount("/",new HostFS()); addMount("/dev",new DevFS()); } } @@ -503,13 +590,13 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public synchronized void removeMount(String path) { if(!path.startsWith("/")) throw new IllegalArgumentException("Mount point doesn't start with a /"); if(path.equals("/")) { - removeMount(-1); + removeMount(-1); } else { path = path.substring(1); int p; for(p=0;p 0) outp--; while(outp > 0 && out[outp] != '/') outp--; - System.err.println("After ..: " + new String(out,0,outp)); + //System.err.println("After ..: " + new String(out,0,outp)); continue; } inp++; @@ -730,13 +825,19 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } public static class HostFS extends FS { - InodeCache inodes = new InodeCache(4096); + InodeCache inodes = new InodeCache(4000); protected File root; public File getRoot() { return root; } private static File hostRootDir() { + if(getSystemProperty("nestedvm.root") != null) { + File f = new File(getSystemProperty("nestedvm.root")); + if(f.isDirectory()) return f; + // fall through to case below + } String cwd = getSystemProperty("user.dir"); File f = new File(cwd != null ? cwd : "."); + if(!f.exists()) throw new Error("Couldn't get File for cwd"); f = new File(f.getAbsolutePath()); while(f.getParent() != null) f = new File(f.getParent()); return f; @@ -747,7 +848,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { if(sep != '/') { char buf[] = path.toCharArray(); for(int i=0;i 0 && pos < size();pos++){ switch(pos) { - case -2: + case -2: case -1: - ino = pos == -1 ? parentInode() : myInode(); + ino = pos == -1 ? parentInode() : myInode(); if(ino == -1) continue; reclen = 9 + (pos == -1 ? 2 : 1); if(reclen > len) break OUTER; @@ -938,7 +1046,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public String name(int n) { switch(n) { - case 0: return "null"; + case 0: return "null"; case 1: return "zero"; case 2: return "fd"; default: return null; @@ -970,6 +1078,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return null; } - public void mkdir(UnixRuntime r, String path, int mode) throws ErrnoException { throw new ErrnoException(EACCES); } - } + public void mkdir(UnixRuntime r, String path, int mode) throws ErrnoException { throw new ErrnoException(EROFS); } + public void unlink(UnixRuntime r, String path) throws ErrnoException { throw new ErrnoException(EROFS); } + } }