import java.io.*;
import java.util.*;
+// FEATURE: vfork
+
public abstract class UnixRuntime extends Runtime implements Cloneable {
/** The pid of this "process" */
private int pid;
// 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
}
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)
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<n;i++) env[i] = defaults[i];
for(int i=0;i<extra.length;i++) env[n++] = extra[i];
case SYS_fork: return sys_fork();
case SYS_pipe: return sys_pipe(a);
case SYS_dup2: return sys_dup2(a,b);
+ case SYS_dup: return sys_dup(a);
case SYS_waitpid: return sys_waitpid(a,b,c);
case SYS_stat: return sys_stat(a,b);
case SYS_lstat: return sys_lstat(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);
+ case SYS_unlink: return sys_unlink(a);
+ case SYS_getppid: return sys_getppid();
default: return super._syscall(syscall,a,b,c,d);
}
FD _open(String path, int flags, int mode) throws ErrnoException {
return gs.open(this,normalizePath(path),flags,mode);
}
+
+ private int sys_getppid() {
+ return parent == null ? 1 : parent.pid;
+ }
/** The kill syscall.
SIGSTOP, SIGTSTO, SIGTTIN, and SIGTTOUT pause the process.
private int exec(String normalizedPath, String[] argv, String[] envp) throws ErrnoException {
if(argv.length == 0) argv = new String[]{""};
+ // NOTE: For this little hack to work nestedvm.root MUST be "."
+ /*try {
+ System.err.println("Execing normalized path: " + normalizedPath);
+ if(true) return exec(new Interpreter(normalizedPath),argv,envp);
+ } catch(IOException e) { throw new Error(e); }*/
+
Object o = gs.exec(this,normalizedPath);
if(o == null) return -ENOENT;
if(o instanceof Class) {
Class c = (Class) o;
try {
- return exec((UnixRuntime) c.newInstance(),argv,envp);
+ return exec((UnixRuntime) c.newInstance(),argv,envp);
} catch(Exception e) {
- e.printStackTrace();
+ e.printStackTrace();
return -ENOEXEC;
}
} else {
return 0;
}
+ private int sys_dup(int oldd) {
+ if(oldd < 0 || oldd >= 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;
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;
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;
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");
}
}
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 {
}
public synchronized Object exec(UnixRuntime r, String path) throws ErrnoException {
+ // FIXME: Hideous hack to make a standalone busybox possible
+ if(path.equals("bin/busybox") && r.getClass().getName().endsWith("BusyBox"))
+ return r.getClass();
FStat fstat = stat(r,path);
if(fstat == null) return null;
long mtime = fstat.mtime();
// 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
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++;
}
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;
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);
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); }
+ }
}