// Copyright 2003 Brian Alliet
// Based on org.xwt.imp.MIPS by Adam Megacz
// Portions Copyright 2003 Adam Megacz
// Copyright 2003 Brian Alliet
// Based on org.xwt.imp.MIPS by Adam Megacz
// Portions Copyright 2003 Adam Megacz
public ExecutionException exitException;
/** Table containing all open file descriptors. (Entries are null if the fd is not in use */
public ExecutionException exitException;
/** Table containing all open file descriptors. (Entries are null if the fd is not in use */
/** Subclasses should set the CPUState to the state held in <i>state</i> */
protected abstract void setCPUState(CPUState state);
/** Subclasses should set the CPUState to the state held in <i>state</i> */
protected abstract void setCPUState(CPUState state);
+ /** True to enabled a few hacks to better support the win32 console */
+ final static boolean win32Hacks;
+
+ static {
+ String os = Platform.getProperty("os.name");
+ String prop = Platform.getProperty("nestedvm.win32hacks");
+ if(prop != null) { win32Hacks = Boolean.valueOf(prop).booleanValue(); }
+ else { win32Hacks = os != null && os.toLowerCase().indexOf("windows") != -1; }
+ }
+
- protected Runtime(int pageSize, int totalPages) {
+ protected Runtime(int pageSize, int totalPages) { this(pageSize, totalPages,false); }
+ protected Runtime(int pageSize, int totalPages, boolean exec) {
if(pageSize <= 0) throw new IllegalArgumentException("pageSize <= 0");
if(totalPages <= 0) throw new IllegalArgumentException("totalPages <= 0");
if((pageSize&(pageSize-1)) != 0) throw new IllegalArgumentException("pageSize not a power of two");
if(pageSize <= 0) throw new IllegalArgumentException("pageSize <= 0");
if(totalPages <= 0) throw new IllegalArgumentException("totalPages <= 0");
if((pageSize&(pageSize-1)) != 0) throw new IllegalArgumentException("pageSize not a power of two");
-
- InputStream stdin = Boolean.valueOf(Platform.getProperty("nestedvm.textstdin")).booleanValue() ? new TextInputStream(System.in) : System.in;
- addFD(new TerminalFD(stdin));
- addFD(new TerminalFD(System.out));
- addFD(new TerminalFD(System.err));
+
+ if(!exec) {
+ fds = new FD[OPEN_MAX];
+ closeOnExec = new boolean[OPEN_MAX];
+
+ InputStream stdin = win32Hacks ? new Win32ConsoleIS(System.in) : System.in;
+ addFD(new TerminalFD(stdin));
+ addFD(new TerminalFD(System.out));
+ addFD(new TerminalFD(System.err));
+ }
private void __execute() {
try {
_execute();
} catch(FaultException e) {
if(STDERR_DIAG) e.printStackTrace();
private void __execute() {
try {
_execute();
} catch(FaultException e) {
if(STDERR_DIAG) e.printStackTrace();
if((flags & ~(3|O_CREAT|O_EXCL|O_APPEND|O_TRUNC)) != 0) {
if(STDERR_DIAG)
System.err.println("WARNING: Unsupported flags passed to open(\"" + f + "\"): " + toHex(flags & ~(3|O_CREAT|O_EXCL|O_APPEND|O_TRUNC)));
if((flags & ~(3|O_CREAT|O_EXCL|O_APPEND|O_TRUNC)) != 0) {
if(STDERR_DIAG)
System.err.println("WARNING: Unsupported flags passed to open(\"" + f + "\"): " + toHex(flags & ~(3|O_CREAT|O_EXCL|O_APPEND|O_TRUNC)));
- private int sys_exit(int status) {
+ void exit(int status, boolean fromSignal) {
+ if(fromSignal && fds[2] != null) {
+ try {
+ byte[] msg = getBytes("Process exited on signal " + (status - 128) + "\n");
+ fds[2].write(msg,0,msg.length);
+ } catch(ErrnoException e) { }
+ }
/** The syscall dispatcher.
The should be called by subclasses when the syscall instruction is invoked.
<i>syscall</i> should be the contents of V0 and <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> should be
/** The syscall dispatcher.
The should be called by subclasses when the syscall instruction is invoked.
<i>syscall</i> should be the contents of V0 and <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> should be
protected final int syscall(int syscall, int a, int b, int c, int d, int e, int f) {
try {
int n = _syscall(syscall,a,b,c,d,e,f);
protected final int syscall(int syscall, int a, int b, int c, int d, int e, int f) {
try {
int n = _syscall(syscall,a,b,c,d,e,f);
case SYS_getpagesize: return sys_getpagesize();
case SYS_fcntl: return sys_fcntl(a,b,c);
case SYS_sysconf: return sys_sysconf(a);
case SYS_getpagesize: return sys_getpagesize();
case SYS_fcntl: return sys_fcntl(a,b,c);
case SYS_sysconf: return sys_sysconf(a);
case SYS_memcpy: memcpy(a,b,c); return a;
case SYS_memset: memset(a,b,c); return a;
case SYS_memcpy: memcpy(a,b,c); return a;
case SYS_memset: memset(a,b,c); return a;
public int xmalloc(int size) { int p=malloc(size); if(p==0) throw new RuntimeException("malloc() failed"); return p; }
public int xrealloc(int addr,int newsize) { int p=realloc(addr,newsize); if(p==0) throw new RuntimeException("realloc() failed"); return p; }
public int realloc(int addr, int newsize) { try { return call("realloc",addr,newsize); } catch(CallException e) { return 0; } }
public int xmalloc(int size) { int p=malloc(size); if(p==0) throw new RuntimeException("malloc() failed"); return p; }
public int xrealloc(int addr,int newsize) { int p=realloc(addr,newsize); if(p==0) throw new RuntimeException("realloc() failed"); return p; }
public int realloc(int addr, int newsize) { try { return call("realloc",addr,newsize); } catch(CallException e) { return 0; } }
public int getdents(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); }
public int getdents(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); }
/** Return a Seekable object representing this file descriptor (can be read only)
This is required for exec() */
Seekable seekable() { return null; }
/** Return a Seekable object representing this file descriptor (can be read only)
This is required for exec() */
Seekable seekable() { return null; }
public TerminalFD(OutputStream os) { this(null,os); }
public TerminalFD(InputStream is, OutputStream os) { super(is,os); }
public void _close() { /* noop */ }
public TerminalFD(OutputStream os) { this(null,os); }
public TerminalFD(InputStream is, OutputStream os) { super(is,os); }
public void _close() { /* noop */ }
public int read() throws IOException {
if(pushedBack != -1) { int c = pushedBack; pushedBack = -1; return c; }
int c = parent.read();
public int read() throws IOException {
if(pushedBack != -1) { int c = pushedBack; pushedBack = -1; return c; }
int c = parent.read();
- public static class FStat {
- public static final int S_IFIFO = 0010000;
- public static final int S_IFCHR = 0020000;
- public static final int S_IFDIR = 0040000;
- public static final int S_IFREG = 0100000;
+ public abstract static class FStat {
+ public static final int S_IFIFO = 0010000;
+ public static final int S_IFCHR = 0020000;
+ public static final int S_IFDIR = 0040000;
+ public static final int S_IFREG = 0100000;
+ public static final int S_IFSOCK = 0140000;
public int nlink() { return 0; }
public int uid() { return 0; }
public int gid() { return 0; }
public int nlink() { return 0; }
public int uid() { return 0; }
public int gid() { return 0; }
public int ctime() { return 0; }
public int blksize() { return 512; }
public int blocks() { return (size()+blksize()-1)/blksize(); }
public int ctime() { return 0; }
public int blksize() { return 512; }
public int blocks() { return (size()+blksize()-1)/blksize(); }
+
+ public abstract int dev();
+ public abstract int type();
+ public abstract int inode();
+ }
+
+ public static class SocketFStat extends FStat {
+ public int dev() { return -1; }
+ public int type() { return S_IFSOCK; }
+ public int inode() { return hashCode() & 0x7fff; }