X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FUnixRuntime.java;h=2b32965eeee982aab2fe03bd94aeb3a64e801d45;hb=b6be9bcc91cf8e995a0e616a480813cdbef09dc2;hp=32a3c7541aa667a1adafabb8b057e0ba651dcaad;hpb=897fa3c89674460aa4fad275f263cea2b341420d;p=nestedvm.git diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 32a3c75..2b32965 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -3,6 +3,10 @@ package org.ibex.nestedvm; import org.ibex.nestedvm.util.*; import java.io.*; import java.util.*; +import java.net.Socket; +import java.net.ServerSocket; + +// FEATURE: vfork public abstract class UnixRuntime extends Runtime implements Cloneable { /** The pid of this "process" */ @@ -33,7 +37,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,7 +65,7 @@ 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) @@ -69,6 +75,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { 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= 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 = gs.stat(this,normalizePath(cstring(cstring))); if(s == null) return -ENOENT; @@ -451,6 +490,11 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { 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; @@ -480,12 +524,71 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return n; } + private static class SocketFD extends InputOutputStreamFD { + private final Socket s; + + public SocketFD(Socket s) throws IOException { + super(s.getInputStream(),s.getOutputStream()); + this.s = s; + } + + public void _close() { try { s.close(); } catch(IOException e) { } } + } + + public int sys_opensocket(int cstring, int port) throws FaultException, ErrnoException { + String hostname = cstring(cstring); + try { + FD fd = new SocketFD(new Socket(hostname,port)); + int n = addFD(fd); + if(n == -1) fd.close(); + return n; + } catch(IOException e) { + return -EIO; + } + } + + private static class ListenSocketFD extends FD { + ServerSocket s; + public ListenSocketFD(ServerSocket s) { this.s = s; } + public int flags() { return 0; } + // FEATURE: What should these be? + public FStat _fstat() { return new FStat(); } + public void _close() { try { s.close(); } catch(IOException e) { } } + } + + public int sys_listensocket(int port) { + try { + ListenSocketFD fd = new ListenSocketFD(new ServerSocket(port)); + int n = addFD(fd); + if(n == -1) fd.close(); + return n; + } catch(IOException e) { + return -EIO; + } + } + + public int sys_accept(int fdn) { + if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; + if(fds[fdn] == null) return -EBADFD; + if(!(fds[fdn] instanceof ListenSocketFD)) return -EBADFD; + try { + ServerSocket s = ((ListenSocketFD)fds[fdn]).s; + SocketFD fd = new SocketFD(s.accept()); + int n = addFD(fd); + if(n == -1) fd.close(); + return n; + } catch(IOException e) { + return -EIO; + } + } + // FEATURE: Run through the fork/wait stuff one more time public static class GlobalState { protected static final int OPEN = 1; 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; @@ -503,7 +606,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } } - private static class MP { + private static class MP implements Comparable { public MP(String path, FS fs) { this.path = path; this.fs = fs; } public String path; public FS fs; @@ -589,6 +692,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { case STAT: return fs.stat(r,path); case LSTAT: return fs.lstat(r,path); case MKDIR: fs.mkdir(r,path,arg1); return null; + case UNLINK: fs.unlink(r,path); return null; default: throw new Error("should never happen"); } } @@ -597,6 +701,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public final FStat stat(UnixRuntime r, String path) throws ErrnoException { return (FStat) fsop(STAT,r,path,0,0); } public final FStat lstat(UnixRuntime r, String path) throws ErrnoException { return (FStat) fsop(LSTAT,r,path,0,0); } public final void mkdir(UnixRuntime r, String path, int mode) throws ErrnoException { fsop(MKDIR,r,path,mode,0); } + public final void unlink(UnixRuntime r, String path) throws ErrnoException { fsop(UNLINK,r,path,0,0); } private Hashtable execCache = new Hashtable(); private static class CacheEnt { @@ -607,6 +712,9 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } public synchronized Object exec(UnixRuntime r, String path) throws ErrnoException { + // FIXME: Hideous hack to make a standalone busybox possible + if(path.equals("bin/busybox") && Boolean.valueOf(getSystemProperty("nestedvm.busyboxhack")).booleanValue()) + return r.getClass(); FStat fstat = stat(r,path); if(fstat == null) return null; long mtime = fstat.mtime(); @@ -708,6 +816,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { // If this returns null it'll be turned into an ENOENT public abstract FStat stat(UnixRuntime r, String path) throws ErrnoException; public abstract void mkdir(UnixRuntime r, String path, int mode) throws ErrnoException; + public abstract void unlink(UnixRuntime r, String path) throws ErrnoException; } // FEATURE: chroot support in here @@ -731,7 +840,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { path.getChars(0,path.length(),in,0); while(in[inp] != 0) { - if(inp != 0) { + if(inp != 0 || cwdl==0) { if(in[inp] != '/') { out[outp++] = in[inp++]; continue; } while(in[inp] == '/') inp++; } @@ -784,8 +893,14 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { 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; @@ -815,6 +930,13 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return r.hostFSOpen(f,flags,mode,this); } + public void unlink(UnixRuntime r, String path) throws ErrnoException { + File f = hostFile(path); + if(r.sm != null && !r.sm.allowUnlink(f)) throw new ErrnoException(EPERM); + if(!f.exists()) throw new ErrnoException(ENOENT); + if(!f.delete()) throw new ErrnoException(EPERM); + } + public FStat stat(UnixRuntime r, String path) throws ErrnoException { File f = hostFile(path); if(r.sm != null && !r.sm.allowStat(f)) throw new ErrnoException(EACCES); @@ -927,16 +1049,12 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } 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 int inode() { return ZERO_INODE; } }; } }; 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; } @@ -1019,6 +1137,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); } + } }