import java.io.*; import java.util.Vector; //Currently The VM Monitor, Pipe Manager, Process Manager, and Stream Manager are all in this single class //Will later separate and create a SYSAPI class that exposes certain methods to VMs. class ProcessManager { //private Vector ProcessArray = new Vector(5,1); }; class StreamManager { }; class PipeManager { }; //public class SYSAPI //{ //}; public class VMMonitor { //private Handle chandle; //private boolean ConsoleAlive = false; private Vector ConsoleArray = new Vector(5,1); private Vector UserArray = new Vector(5,1); public VMMonitor() { } public void OsvmMain() { VMachine vm1 = null; FileClassLoader fileclass = null; fileclass = new FileClassLoader(); fileclass.bindir = "C:\\java\\OSVM\\bin\\"; Class newclass = null; Handle dh1 = OpenDevice("keyboard",null); Handle dh2 = OpenDevice("display",null); try { newclass = fileclass.loadCmd("login"); Handle vmh1 = CreateVM(dh1,dh2,newclass,null,"",null,null,null,0); //This is the only case where a VMachine gets started outside of Compute(Handle) ((VMachine)vmh1.getType()).start(); } catch(Exception ex) { System.out.println("Program could not run login."); } } public Handle OpenDevice(String device,String currentUser) { //Only One Handle for both devices since it is the same Object Handling it ConsoleWindow console; String ThreadID; int i; //This case is used for initial console-user creation if(currentUser == null) {// No initial User or Console if(device == "keyboard") { if(ConsoleArray.size() == 0) { console = new ConsoleWindow("OSVM"); ConsoleArray.add(console); } else { console = ((ConsoleWindow)ConsoleArray.get(0)); } ThreadID = console.getClass().getName() + "-" + console.hashCode(); Handle chandle = new Handle(console,1,ThreadID);//Create method for unique IDs return chandle; } if(device == "display") { if(ConsoleArray.size() == 0) { console = new ConsoleWindow("OSVM"); ConsoleArray.add(console); } else { console = ((ConsoleWindow)ConsoleArray.get(0)); } ThreadID = console.getClass().getName() + "-" + console.hashCode(); Handle chandle = new Handle(console,1,ThreadID);//Create method for unique IDs return chandle; } } //This case is used for all other device requests if(device == "keyboard") { for(i=0;i < UserArray.size() && getUser(i).getName() != currentUser;i++); if(i >= UserArray.size() || i >= ConsoleArray.size()) { console = new ConsoleWindow("OSVM - " + currentUser); ConsoleArray.add(console); } else { console = ((ConsoleWindow)ConsoleArray.get(i)); } ThreadID = console.getClass().getName() + "-" + console.hashCode(); Handle chandle = new Handle(console,1,ThreadID);//Create method for unique IDs return chandle; } if(device == "display") { for(i=0;i < UserArray.size() && getUser(i).getName() != currentUser;i++); if(i >= UserArray.size() || i >= ConsoleArray.size()) { console = new ConsoleWindow("OSVM - " + currentUser); ConsoleArray.add(console); } else { console = ((ConsoleWindow)ConsoleArray.get(i)); } ThreadID = console.getClass().getName() + "-" + console.hashCode(); Handle chandle = new Handle(console,2,ThreadID);//Create method for unique IDs return chandle; } else { return new Handle(null,0,""); } } public void setTitle(String username) { int i; for(i=0;i < UserArray.size() && getUser(i).getName() != username;i++); ((ConsoleWindow)ConsoleArray.get(i)).setTitle("OSVM - " + username); } public Handle CreateVM(Handle IN,Handle OUT,Class VMClass,String owner,String args,VMachine Parent,Vector sib,Vector child,int undone) { // Modify CreateVM so that it updates parent and sibling vms when new child vm added, eg. vm with a parent try { VMachine vm1 = (VMachine) VMClass.newInstance(); String ThreadID = VMClass.getName() + "-" + vm1.hashCode(); ((Thread)vm1).setName(ThreadID); Handle vmh1 = new Handle(vm1,3,ThreadID); ((VMachine)vm1).prepareVM(IN,OUT,vmh1,owner,args,Parent,sib,child,undone,this); if(Parent != null) { Parent.child.add(vm1); Parent.undone++; } return vmh1; } catch(Exception ex) { System.out.println("Exception while Creating Virtual Machine"); return null; } //Look In Parent VMachine for children //Make Parent's Children this VM's siblings //Add this new VM to the Parent's child Vector //current default access = 3, read & write //Create method for unique IDs } public synchronized void DeleteVM(Handle vmh,String userVM) { int i = 0; for(i=0;getUser(i).getName() != userVM;i++); getUser(i).removeHandle(vmh); try { if(((VMachine)vmh.getType()).Parent != null) { for(i=0;!vmh.getType().equals(((VMachine)vmh.getType()).Parent.child.get(i));i++); //Delete child from Parent of this VM ((VMachine)vmh.getType()).Parent.child.remove(i); } else { if(getUser(i).getCount()==0)//logout and exit {//Create a logout that waits for users VM's to finish and closes User //logout---- ((ConsoleWindow)ConsoleArray.get(i)).dispose(); ConsoleArray.remove(i); UserArray.remove(i); //----- if(UserArray.size()==0) {//No users left System.exit(0); } } } } catch(Exception ex) { System.out.println(ex); } //Delete from siblings //Delete from VMachines Vector //currentUser.removeHandle(vmh); //Check if last shell was deleted and if so, logout } public synchronized void Exit(Handle vmh,String userVM) { if(((VMachine)vmh.getType()).Parent != null) { ((VMachine)vmh.getType()).Parent.undone--; } DeleteVM(vmh,userVM); try { notifyAll(); } catch(Exception ex) { System.out.println(ex); } } public void Compute(Handle vmh) { int i = 0; int childsize = ((VMachine)vmh.getType()).child.size(); try { for(i=0;i0) { wait(); } } } catch(InterruptedException ex) { System.out.println("Exception while stopping parent VM"); } } public void Write(Handle OUT, String output) { //looks at handle's output handle and decides where to send it. //case where handle is shell ((ConsoleWindow)OUT.getType()).out.print(output); ((ConsoleWindow)OUT.getType()).out.flush(); } public String Read(Handle IN) { String data = ""; try { //case where handle is shell data = ((ConsoleWindow)IN.getType()).in.readLine(); } catch(IOException ex) { System.out.println("Exception while reading from keyboard."); } return data; } public User getUser(int index) { return ((User)UserArray.get(index)); } public User findUser(String username) { int i; for(i=0;getUser(i).getName() != username;i++); return getUser(i); } public void setUser(User newUser) { UserArray.add(newUser); } /* public synchronized void requestinput() { //SYSAPI METHOD try { String rawdata = console.in.readLine(); byte pipedata[]; pipedata = rawdata.getBytes(); outpipe.write(pipedata,0,pipedata.length); } catch(Exception ex) { console.out.println("Error requesting input."); ex.printStackTrace(); } } public synchronized void requestoutput() { //SYSAPI METHOD try { byte[] pipedata = new byte[inpipe.available()]; // Pipe Return Buffer of Specified Size //outpipe could contain control characters to indicate need for input on inpipe. //console.out.println("Pipe Data Available: " + inpipe.available()); if(inpipe.read(pipedata,0,inpipe.available()) != -1) { //Closes Pipes used by previously created worker thread //inpipe.close(); //outpipe.close(); String strdata = new String(pipedata); //SOLVEDBUG Printing to console.out is locking some thread //Excess buffer length created string with many null characters //that froze bufferreader object console.out.println(strdata); } } catch(Exception ex) { } } */ }; class Handle { private Object type; private int access; private String ThreadID; public Handle() { } public Handle(Object newType, int newAccess, String newID) { type = newType; access = newAccess; ThreadID = newID; } /*public void modifyHandle(Object newType, int newAccess, int newID) { type = newType; access = newAccess; ID = newID; }*/ public Object getType() { return type; } public int getAccess() { return access; } public String getID() { return ThreadID; } };