// COM3336 Operating Systems // Homework 2 part 1 // John Sung // Started: 10/22/1999 // import java.util.*; import java.io.*; import ThreadMutex; import OutputInstreamThread; // the class that will execute a command. public class CommandExecutor extends Thread { /////////////////////////////////////////// // private variables // the command and args that this thread is going // to attempt to execute. String CmdAndArgs; // the reference to the thread mutex // that the main thread is waiting for. ThreadMutex ThreadCounterMutex; // the shell system in which // we should be executing this command ShellSystem FileSystem; // constructor for the command executor. // pass in the command and args string. public CommandExecutor(String cmdAndArgs, ThreadMutex mutex, ShellSystem fsystem) { // set the mutex in which the higher level command // will be waiting on ThreadCounterMutex = mutex; // add myself to the count ThreadCounterMutex.changeThreadCount(1); // set the command and arg string CmdAndArgs = cmdAndArgs; // set the shell system FileSystem = fsystem; } // check to see if we have correct number of tokens. // returns true if successful, returns false if fails. boolean checkNumOfTokens(PrintStream out, int expected, int actual, String cmdName) { // check for correct number of arguments if (expected != actual) { // print out some error System.err.println(cmdName + ": Expected " + expected + " but got " + actual + "."); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return false; } return true; } // the run function to be executed when this // thread is running. public void run () { // use stringTokenizer to generate an array of words. StringTokenizer strTokens = new StringTokenizer(CmdAndArgs); // number of tokens found int numOfTokens = strTokens.countTokens(); // if the number of tokens is 0 then just return if (strTokens.countTokens() == 0) { // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // create the array of strings String[] argVec = new String[numOfTokens]; // index into the argVec int index = 0; // loop through and add in all of the args in the argv. while (strTokens.hasMoreTokens()) { // add the token to the argVec array argVec[index++] = strTokens.nextToken(); } // the command that we're attempting to execute String cmdName = argVec[0]; // check to see if the first element in the // argVec is an "exit". if (cmdName.compareTo("exit") == 0) { // exit the "shell" program System.out.println("System Exiting..."); System.exit(0); } // check for the makedir command if (cmdName.compareTo("mkdir") == 0) { // check for correct number of arguments if (!checkNumOfTokens(System.out, 1, numOfTokens-1, "mkdir")) { return; } // now make the directory FileSystem.makeDir(argVec[1]); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the cd command if (cmdName.compareTo("cd") == 0) { if (!checkNumOfTokens(System.out, 1, numOfTokens-1, "cd")) { return; } // check to see if we're cd'ing up. if (argVec[1].compareTo("..") == 0) { // if it is then just move up to the parent directory FileSystem.changeDirUp(); } else { // move down to the specified directory FileSystem.changeDirDown(argVec[1]); } // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the cp command if (cmdName.compareTo("cp") == 0) { // check for correct number of arguments if (!checkNumOfTokens(System.out, 3, numOfTokens-1, "cp")) { return; } // check to make sure that we have -r as argv[1] if (argVec[1].compareTo("-r") != 0) { // print out some error System.err.println("cp: Expected -r as the first argument, but encountered: " + argVec[1]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check to make sure that we have ../* as argv[2] if (argVec[2].compareTo("../*") != 0) { // print out some error System.err.println("cp: Expected ../* as the second argument, but encountered: " + argVec[2]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check to make sure that we have . as argv[3] if (argVec[3].compareTo(".") != 0) { // print out some error System.err.println("cp: Expected . as the third argument, but encountered: " + argVec[3]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // now do a recursive copy FileSystem.recursiveCopy(); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the cd command if (cmdName.compareTo("du") == 0) { //System.out.println("numoftokens = " + numOfTokens); // check for correct number of arguments if (!checkNumOfTokens(System.out, 1, numOfTokens-1, "du")) { return; } // check to make sure that we have . as argv[1] if (argVec[1].compareTo(".") != 0 && argVec[1].compareTo("-a") != 0) { // print out some error System.err.println("du: Expected . or -a as the first argument, but encountered: " + argVec[1]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } if (argVec[1].compareTo(".") == 0) // now do a disk usage command FileSystem.diskUsage(); else // do the diskUsage All FileSystem.diskUsageAll(); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the cd command if (cmdName.compareTo("find") == 0) { // check for correct number of arguments if (!checkNumOfTokens(System.out, 4, numOfTokens-1, "find")) { return; } // check to make sure that we have . as argv[1] if (argVec[1].compareTo(".") != 0) { // print out some error System.err.println("find: Expected . as the first argument, but encountered: " + argVec[1]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check to make sure that we have -name as argv[2] if (argVec[2].compareTo("-name") != 0) { // print out some error System.err.println("find: Expected -name as the second argument, but encountered: " + argVec[2]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check to make sure that we have -print as argv[4] if (argVec[4].compareTo("-print") != 0) { // print out some error System.err.println("find: Expected -print as the fourth argument, but encountered: " + argVec[2]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // call the find command FileSystem.find(argVec[3]); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the echo command if (cmdName.compareTo("echo") == 0) { int firstQuote = 0; int secondQuote = 0; // find the first " firstQuote = CmdAndArgs.indexOf('"'); // if the first quote is not found then print out an error message if (firstQuote < 0) { System.err.println("echo: \" not found"); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // find the second " secondQuote = CmdAndArgs.indexOf('"',firstQuote + 1); // if the second quote is not found then print out an error message if (secondQuote < 0) { System.err.println("echo: unmatched \""); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // just output the string in between the quotes System.out.println(CmdAndArgs.substring(firstQuote+1, secondQuote)); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the touch command if (cmdName.compareTo("touch") == 0) { if (!checkNumOfTokens(System.out, 1, numOfTokens-1, "touch")) { return; } // attempt to create the file FileSystem.createFile(argVec[1]); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the touch command if (cmdName.compareTo("rm") == 0) { if (!checkNumOfTokens(System.out, 1, numOfTokens-1, "rm")) { return; } // attempt to remove the file FileSystem.removeFile(argVec[1]); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the rmdir command if (cmdName.compareTo("rmdir") == 0) { if (!checkNumOfTokens(System.err, 1, numOfTokens-1, "rmdir")) { return; } // attempt to create the file FileSystem.removeDir(argVec[1]); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // check for the ln -s command if (cmdName.compareTo("ln") == 0) { if (!checkNumOfTokens(System.err, 3, numOfTokens-1, "ln")) { return; } // attempt to create the file FileSystem.createSymbolicLink(argVec[2], argVec[3]); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } // print out an error saying that the command specified is an unknown // command System.err.println("Unknown command: " + argVec[0]); System.err.println("Offending command line: " + CmdAndArgs); // take myself off the thread counter ThreadCounterMutex.changeThreadCount(-1); return; } }