X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FUnixRuntime.java;h=24a7967f0e598f0afc1d8a3cb4bb1fff044caf1b;hp=135348fe97214106fd5bd2f50b88f69963e6d9e5;hb=034a42fa65955289442614ef9914e5474fac62aa;hpb=40de2c62cb907622ff6f5fcdbeccc8773a1d7b2d diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 135348f..24a7967 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -7,7 +7,10 @@ import java.util.*; // FEATURE: 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 { +// FEATURE: Throw ErrnoException and catch in syscall whereever possible +// (only in cases where we've already paid the price for a throw) + +public abstract class UnixRuntime extends Runtime implements Cloneable { /** The pid of this "process" */ private int pid; private int ppid; @@ -17,7 +20,7 @@ public abstract class UnixRuntime extends Runtime { private FS fs; public FS getFS() { return fs; } public void setFS(FS fs) { - if(state >= RUNNING) throw new IllegalStateException("Can't change fs while process is running"); + if(state != STOPPED) throw new IllegalStateException("Can't change fs while process is running"); this.fs = fs; } @@ -25,6 +28,9 @@ public abstract class UnixRuntime extends Runtime { "" = root, "bin" = /bin "usr/bin" = /usr/bin */ private String cwd; + /** The runtime that should be run next when in state == EXECED */ + private UnixRuntime execedRuntime; + /* Static stuff */ // FEATURE: Most of this is O(n) or worse - fix it private final Object waitNotification = new Object(); @@ -49,8 +55,8 @@ public abstract class UnixRuntime extends Runtime { } } - public UnixRuntime(int pageSize, int totalPages, boolean allowEmptyPages) { - super(pageSize,totalPages,allowEmptyPages); + public UnixRuntime(int pageSize, int totalPages) { + super(pageSize,totalPages); FS root = new HostFS(); FS dev = new DevFS(); @@ -111,11 +117,11 @@ public abstract class UnixRuntime extends Runtime { if(ppid == 0) removeTask(this); for(int i=0;i= sp-PAGE_SIZE*2) - System.arraycopy(writePages[i],0,r.writePages[i],0,PAGE_WORDS); - } else { - r.readPages[i] = r.readPages[i]; - } - } - state.r[V0] = 0; - state.pc += 4; + + state.r[V0] = 0; // return 0 to child + state.pc += 4; // skip over syscall instruction r.setCPUState(state); r.state = PAUSED; @@ -269,23 +254,108 @@ public abstract class UnixRuntime extends Runtime { } }.start(); - return child_pid; + return childPID; + } + + public static int runAndExec(UnixRuntime r, String argv0, String[] rest) { return runAndExec(r,concatArgv(argv0,rest)); } + public static int runAndExec(UnixRuntime r, String[] argv) { r.start(argv); return executeAndExec(r); } + + public static int executeAndExec(UnixRuntime r) { + for(;;) { + for(;;) { + if(r.execute()) break; + System.err.println("WARNING: Pause requested while executing runAndExec()"); + } + if(r.state != EXECED) return r.exitStatus(); + r = r.execedRuntime; + } + } + + private String[] readStringArray(int addr) throws ReadFaultException { + 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= 0) return -EACCES; + return -ENOENT; + } + catch(IOException e) { return -EIO; } + catch(FaultException e) { return -EFAULT; }*/ + } + + private int exec(Class c, String[] argv, String[] envp) { + UnixRuntime r; - private int sys_execve(int cstring, int argv, int envp) { - /* try { - String path = cstring(cstring); - FStat stat = fs.stat(path); - - + r = (UnixRuntime) c.newInstance(); + } catch(Exception e) { + return -ENOMEM; } - catch(FaultException e) { return -EFAULT; } - catch(FileNotFoundException e) { return -ENOENT; } - catch(IOException e) { return -EIO; }*/ - throw new Error("FIXME - exec() isn't finished"); + + for(int i=0;i= RUNNING) throw new IllegalStateException("Can't chdir while process is running"); + if(state != STOPPED) throw new IllegalStateException("Can't chdir while process is running"); try { dir = normalizePath(dir); if(fs.stat(dir).type() != FStat.S_IFDIR) throw new FileNotFoundException(); @@ -409,8 +479,10 @@ public abstract class UnixRuntime extends Runtime { public final FD open(String path, int flags, int mode) throws IOException { return (FD) op(OPEN,path,flags,mode); } public final FStat stat(String path) throws IOException { return (FStat) op(STAT,path,0,0); } public final void mkdir(String path) throws IOException { op(MKDIR,path,0,0); } + - // FIXME: inode stuff + // FEATURE: inode stuff + // FEATURE: Implement whatever is needed to get newlib's opendir and friends to work - that patch is a pain protected static FD directoryFD(String[] files, int hashCode) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); @@ -466,6 +538,7 @@ public abstract class UnixRuntime extends Runtime { continue; } inp++; + out[outp++] = '/'; out[outp++] = '.'; } if(outp > 0 && out[outp-1] == '/') outp--; @@ -473,58 +546,6 @@ public abstract class UnixRuntime extends Runtime { return new String(out,0,outp); } - // FIXME: This is probably still buggy - // FEATURE: Remove some of the "should never happen checks" - /*protected static String cleanupPath(String p) throws ErrnoException { - if(p.length() == 0) throw new ErrnoException(ENOENT); - if(needsCleanup(p)) { - char[] in = p.toCharArray(); - char[] out; - int outp ; - if(in[0] == '/') { - out = new char[in.length]; - outp = 0; - } else { - out = new char[cwd.length() + in.length + 1]; - outp = cwd.length(); - for(int i=0;i 0 && out[outp] != '/'); - } else if(in[inp+1] == '/') { - inp++; - } else { - out[outp++] = '/'; - } - } else { - out[outp++] = '/'; - out[outp++] = in[inp++]; - } - } else { - out[outp++] = in[inp++]; - } - } - if(outp == 0) out[outp++] = '/'; - return new String(out,0,outp); - } else { - if(p.startsWith("/")) return p; - StringBuffer sb = new StringBuffer(cwd); - if(!cwd.equals("/")) sb.append('/'); - return sb.append(p).toString(); - } - }*/ - public static class MountPointFS extends FS { private static class MP { public MP(String path, FS fs) { this.path = path; this.fs = fs; } @@ -545,7 +566,7 @@ public abstract class UnixRuntime extends Runtime { if(path.length() == 0) throw new IllegalArgumentException("Zero length mount point path"); return path; } - public FS get(String path) { + public synchronized FS get(String path) { path = fixup(path); int f = path.charAt(0) & 0x7f; for(int i=0;mps[f] != null && i < mps[f].length;i++) @@ -553,7 +574,7 @@ public abstract class UnixRuntime extends Runtime { return null; } - public void add(String path, FS fs) { + public synchronized void add(String path, FS fs) { if(get(path) != null) throw new IllegalArgumentException("mount point already exists"); path = fixup(path); int f = path.charAt(0) & 0x7f; @@ -565,7 +586,7 @@ public abstract class UnixRuntime extends Runtime { mps[f] = newList; } - public void remove(String path) { + public synchronized void remove(String path) { path = fixup(path); if(get(path) == null) throw new IllegalArgumentException("mount point doesn't exist"); int f = path.charAt(0) & 0x7f; @@ -593,36 +614,7 @@ public abstract class UnixRuntime extends Runtime { return root.op(op,path,arg1,arg2); } } - - // FEATURE: Probably should make this more general - support mountpoints, etc - /*public class UnixOverlayFS extends FS { - private final FS root; - private final FS dev = new DevFS(); - public UnixOverlayFS(FS root) { - this.root = root; - } - private String devPath(String path) { - if(path.startsWith("/dev")) { - if(path.length() == 4) return "/"; - if(path.charAt(4) == '/') return path.substring(4); - } - return null; - } - public FD open(String path, int flags, int mode) throws IOException{ - String dp = devPath(path); - return dp == null ? root.open(path,flags,mode) : dev.open(dp,flags,mode); - } - public FStat stat(String path) throws IOException { - String dp = devPath(path); - return dp == null ? root.stat(path) : dev.stat(dp); - } - public void mkdir(String path) throws IOException { - String dp = devPath(path); - if(dp == null) root.mkdir(path); - else dev.mkdir(dp); - } - }*/ - + public static class HostFS extends FS { protected File root; public File getRoot() { return root; } @@ -635,8 +627,17 @@ public abstract class UnixRuntime extends Runtime { return f; } - private File hostFile(String path) { - if(File.separatorChar != '/') path = path.replace('/',File.separatorChar); + File hostFile(String path) { + char sep = File.separatorChar; + if(sep != '/') { + char buf[] = path.toCharArray(); + for(int i=0;i