jsos

college code for operating system fundamentals in js

git clone https://9o.is/git/jsos.git

shell.js

(22431B)


      1 /* ------------
      2    Shell.js
      3    
      4    The OS Shell - The "command line interface" (CLI) or interpreter for the console.
      5    ------------ */
      6 
      7 // TODO: Write a base class / prototype for system services and let Shell inherit from it.
      8 
      9 function Shell()
     10 {
     11     // Properties
     12     this.promptStr   = "$";
     13     this.commandList = [];
     14     this.curses      = "[fuvg],[cvff],[shpx],[phag],[pbpxfhpxre],[zbgureshpxre],[gvgf]";
     15     this.apologies   = "[sorry]";
     16     // Methods
     17     this.init        = shellInit;
     18     this.putPrompt   = shellPutPrompt;
     19     this.handleInput = shellHandleInput;
     20     this.execute     = shellExecute;
     21 }
     22 
     23 function shellInit()
     24 {
     25     var sc = null;
     26     //
     27     // Load the command list.
     28 
     29     // ver
     30     sc = new ShellCommand();
     31     sc.command = "ver";
     32     sc.description = "- Displays the current version data."
     33     sc.function = shellVer;
     34     this.commandList[this.commandList.length] = sc;
     35     
     36     // help
     37     sc = new ShellCommand();
     38     sc.command = "help";
     39     sc.description = "- This is the help command. Seek help."
     40     sc.function = shellHelp;
     41     this.commandList[this.commandList.length] = sc;
     42     
     43     // shutdown
     44     sc = new ShellCommand();
     45     sc.command = "shutdown";
     46     sc.description = "- Shuts down the virtual OS but leaves the underlying hardware simulation running."
     47     sc.function = shellShutdown;
     48     this.commandList[this.commandList.length] = sc;
     49 
     50     // cls
     51     sc = new ShellCommand();
     52     sc.command = "cls";
     53     sc.description = "- Clears the screen and resets the cursosr position."
     54     sc.function = shellCls;
     55     this.commandList[this.commandList.length] = sc;
     56 
     57     // man <topic>
     58     sc = new ShellCommand();
     59     sc.command = "man";
     60     sc.description = "<topic> - Displays the MANual page for <topic>.";
     61     sc.function = shellMan;
     62     this.commandList[this.commandList.length] = sc;
     63     
     64     // trace <on | off>
     65     sc = new ShellCommand();
     66     sc.command = "trace";
     67     sc.description = "<on | off> - Turns the OS trace on or off.";
     68     sc.function = shellTrace;
     69     this.commandList[this.commandList.length] = sc;
     70 
     71     // rot13 <string>
     72     sc = new ShellCommand();
     73     sc.command = "rot13";
     74     sc.description = "<string> - Does rot13 obfuscation on <string>.";
     75     sc.function = shellRot13;
     76     this.commandList[this.commandList.length] = sc;
     77 
     78     // prompt <string>
     79     sc = new ShellCommand();
     80     sc.command = "prompt";
     81     sc.description = "<string> - Sets the prompt.";
     82     sc.function = shellPrompt;
     83     this.commandList[this.commandList.length] = sc;
     84 
     85     // date
     86     sc = new ShellCommand();
     87     sc.command = "date";
     88     sc.description = "- Displays the current date and time."
     89     sc.function = shellDate;
     90     this.commandList[this.commandList.length] = sc;
     91 
     92     // whereami
     93     sc = new ShellCommand();
     94     sc.command = "whereami";
     95     sc.description = "- Displays where you are."
     96     sc.function = shellWhereami;
     97     this.commandList[this.commandList.length] = sc;
     98 
     99     // qwikerase
    100     sc = new ShellCommand();
    101     sc.command = "qwe";
    102     sc.description = "- QwikErase: Overrides all data in filesystem."
    103     sc.function = shellQuickerase;
    104     this.commandList[this.commandList.length] = sc;
    105 
    106     // status
    107     sc = new ShellCommand();
    108     sc.command = "status";
    109     sc.description = "- Sets the console's status.";
    110     sc.function = shellStatus;
    111     this.commandList[this.commandList.length] = sc;
    112 
    113     // load
    114     sc = new ShellCommand();
    115     sc.command = "load";
    116     sc.description = "- Loads an external program.";
    117     sc.function = shellLoad;
    118     this.commandList[this.commandList.length] = sc;
    119 
    120     // run
    121     sc = new ShellCommand();
    122     sc.command = "run";
    123     sc.description = "- Runs a process.";
    124     sc.function = shellRun;
    125     this.commandList[this.commandList.length] = sc;
    126 
    127     // runall
    128     sc = new ShellCommand();
    129     sc.command = "runall";
    130     sc.description = "- Runs all resident processes.";
    131     sc.function = shellRunAll;
    132     this.commandList[this.commandList.length] = sc;
    133 
    134     // reset
    135     sc = new ShellCommand();
    136     sc.command = "reset";
    137     sc.description = "- Resets the OS.";
    138     sc.function = shellReset;
    139     this.commandList[this.commandList.length] = sc;
    140 
    141     // rrquantum
    142     sc = new ShellCommand();
    143     sc.command = "rrquantum";
    144     sc.description = "- Sets the Round-Robin Quantum.";
    145     sc.function = shellRRQuantum;
    146     this.commandList[this.commandList.length] = sc;
    147 
    148     // processes
    149     sc = new ShellCommand();
    150     sc.command = "processes";
    151     sc.description = "- Shows all active processes' ID.";
    152     sc.function = shellProcesses;
    153     this.commandList[this.commandList.length] = sc;
    154 
    155     // kill 
    156     sc = new ShellCommand();
    157     sc.command = "kill";
    158     sc.description = "- Kills the specified process ID.";
    159     sc.function = shellKill;
    160     this.commandList[this.commandList.length] = sc;
    161 
    162     // change directory 
    163     sc = new ShellCommand();
    164     sc.command = "cd";
    165     sc.description = "- Changes the current working directory.";
    166     sc.function = shellCD;
    167     this.commandList[this.commandList.length] = sc;
    168 
    169     // create directory 
    170     sc = new ShellCommand();
    171     sc.command = "mkdir";
    172     sc.description = "- Creates a new directory in the current directory.";
    173     sc.function = shellCreateDirectory;
    174     this.commandList[this.commandList.length] = sc;
    175 
    176     // create text file 
    177     sc = new ShellCommand();
    178     sc.command = "create";
    179     sc.description = "- Creates a new text file in the current directory.";
    180     sc.function = shellCreateFile;
    181     this.commandList[this.commandList.length] = sc;
    182 
    183     // read 
    184     sc = new ShellCommand();
    185     sc.command = "read";
    186     sc.description = "- Reads a file in the filesystem.";
    187     sc.function = shellRead;
    188     this.commandList[this.commandList.length] = sc;
    189 
    190     // write 
    191     sc = new ShellCommand();
    192     sc.command = "write";
    193     sc.description = "- Writes text to file in the filesystem.";
    194     sc.function = shellWrite;
    195     this.commandList[this.commandList.length] = sc;
    196 
    197     // delete 
    198     sc = new ShellCommand();
    199     sc.command = "delete";
    200     sc.description = "- Deletes a file in the filesystem.";
    201     sc.function = shellDelete;
    202     this.commandList[this.commandList.length] = sc;
    203 
    204     // format 
    205     sc = new ShellCommand();
    206     sc.command = "format";
    207     sc.description = "- Formats entire filesystem.";
    208     sc.function = shellFormat;
    209     this.commandList[this.commandList.length] = sc;
    210 
    211     // ls 
    212     sc = new ShellCommand();
    213     sc.command = "ls";
    214     sc.description = "- Lists the files currently stored on disk.";
    215     sc.function = shellLs;
    216     this.commandList[this.commandList.length] = sc;
    217 
    218     // setcpu 
    219     sc = new ShellCommand();
    220     sc.command = "setcpu";
    221     sc.description = "- Set cpu scheduling to rr, fcfs or priority.";
    222     sc.function = shellSetcpu;
    223     this.commandList[this.commandList.length] = sc;
    224 
    225     // whatcpu 
    226     sc = new ShellCommand();
    227     sc.command = "whatcpu";
    228     sc.description = "- Shows the currently running cpu schedule.";
    229     sc.function = shellWhatcpu;
    230     this.commandList[this.commandList.length] = sc;
    231 
    232     //
    233     // Display the initial prompt.
    234     this.putPrompt();
    235 }
    236 
    237 function shellPutPrompt()
    238 {
    239     _StdIn.putText(this.promptStr);
    240 }
    241 
    242 function shellHandleInput(buffer)
    243 {
    244     krnTrace("Shell Command~" + buffer);
    245     // 
    246     // Parse the input...
    247     //
    248     var userCommand = new UserCommand();
    249     userCommand = shellParseInput(buffer);
    250     // ... and assign the command and args to local variables.
    251     var cmd = userCommand.command;
    252     var args = userCommand.args;
    253     //
    254     // Determine the command and execute it.
    255     //
    256     // Javascript may not support associative arrays (one of the few nice features of PHP, actually)
    257     // so we have to iterate over the command list in attempt to find a match.  TODO: Is there a better way?
    258     var index = 0;
    259     var found = false;
    260     while (!found && index < this.commandList.length)
    261     {
    262         if (this.commandList[index].command === cmd)
    263         {
    264             found = true;
    265             fn = this.commandList[index].function;
    266         }
    267         else
    268         {
    269             ++index;
    270         }
    271     }
    272     if (found)
    273     {
    274         this.execute(fn, args);
    275     }
    276     else
    277     {
    278         // It's not found, so check for curses and apologies before declaring the command invalid.
    279         if (this.curses.indexOf("[" + rot13(cmd) + "]") >= 0)      // Check for curses.
    280         {
    281             this.execute(shellCurse);
    282         }
    283         else if (this.apologies.indexOf("[" + cmd + "]") >= 0)      // Check for apoligies.
    284         {
    285             this.execute(shellApology);
    286         }
    287         else if(cmd == "") 
    288         {
    289            _StdIn.advanceLine();
    290            _StdIn.putText(this.promptStr);
    291         }
    292         else    // It's just a bad command.
    293         {
    294             this.execute(shellInvalidCommand);
    295         }
    296     }
    297 }
    298 
    299 
    300 function shellParseInput(buffer)
    301 {
    302     var retVal = new UserCommand();
    303     //
    304     // 1. Remove leading and trailing spaces.
    305     buffer = trim(buffer);
    306     // 2. Lower-case it.
    307     buffer = buffer.toLowerCase();
    308     // 3. Separate on spaces so we can determine the command and command-line args, if any.
    309     var tempList = buffer.split(" ");
    310     // 4. Take the first (zeroth) element and use that as the command.
    311     var cmd = tempList.shift();  // Yes, you can do that to an array in Javascript.  See the Queue class.
    312     // 4.1 Remove any left-over spaces.
    313     cmd = trim(cmd);
    314     // 4.2 Record it in the return value.
    315     retVal.command = cmd;
    316     //
    317     // 5. Now create the args array from what's left.
    318     for (var i in tempList)
    319     {
    320         var arg = trim(tempList[i]);
    321         if (arg != "")
    322         {
    323             retVal.args[retVal.args.length] = tempList[i];
    324         }
    325     }
    326     return retVal;
    327 }
    328 
    329 
    330 function shellExecute(fn, args)
    331 {
    332     // we just got a command, so advance the line... 
    333     _StdIn.advanceLine();
    334     // .. call the command function passing in the args...
    335     fn(args);
    336     // Check to see if we need to advance the line again
    337     if (_StdIn.CurrentXPosition > 0)
    338     {
    339         _StdIn.advanceLine();
    340     }
    341     // ... and finally write the prompt again.
    342     this.putPrompt();
    343 }
    344 
    345 
    346 //
    347 // The rest of these functions ARE NOT part of the Shell "class" (prototype, more accurately), 
    348 // as they are not denoted in the constructor.  The idea is that you cannot execute them from
    349 // elsewhere as shell.xxx .  In a better world, and a more perfect Javascript, we'd be 
    350 // able to make then private.  (Actually, we can. Someone look at Crockford's stuff and give me the details, please.)
    351 //
    352 
    353 //
    354 // An "interior" or "private" class (prototype) used only inside Shell() (we hope).
    355 //
    356 function ShellCommand()     
    357 {
    358     // Properties
    359     this.command = "";
    360     this.description = "";
    361     this.function = "";
    362 }
    363 
    364 //
    365 // Another "interior" or "private" class (prototype) used only inside Shell() (we hope).
    366 //
    367 function UserCommand()
    368 {
    369     // Properties
    370     this.command = "";
    371     this.args = [];
    372 }
    373 
    374 
    375 //
    376 // Shell Command Functions.  Again, not part of Shell() class per se', just called from there.
    377 //
    378 function shellInvalidCommand()
    379 {
    380     _StdIn.putText("Invalid Command. ");
    381     if (_SarcasticMode)
    382     {
    383         _StdIn.putText("Duh. Go back to your Speak & Spell.");
    384     }
    385     else
    386     {
    387         _StdIn.putText("Type 'help' for, well... help.");
    388     }
    389 }
    390 
    391 function shellCurse()
    392 {
    393     _StdIn.putText("Oh, so that's how it's going to be, eh? Fine.");
    394     _StdIn.advanceLine();
    395     _StdIn.putText("Bitch.");
    396     _SarcasticMode = true;
    397 }
    398 
    399 function shellApology()
    400 {
    401     _StdIn.putText("Okay. I forgive you. This time.");
    402     _SarcasticMode = false;
    403 }
    404 
    405 function shellVer(args)
    406 {
    407     _StdIn.putText(APP_NAME + " v." + APP_VERSION);    
    408 }
    409 
    410 function shellHelp(args)
    411 {
    412     _StdIn.putText("Commands:");
    413     for (i in _OsShell.commandList)
    414     {
    415         _StdIn.advanceLine();
    416         _StdIn.putText("  " + _OsShell.commandList[i].command + " " + _OsShell.commandList[i].description);
    417     }    
    418 }
    419 
    420 function shellShutdown(args)
    421 {
    422      _StdIn.putText("Shutting down...");
    423      // Call Kernal shutdown routine.
    424     krnShutdown();   
    425     // TODO: Stop the final prompt from being displayed.  If possible.  Not a high priority.  (Damn OCD!)
    426 }
    427 
    428 function shellCls(args)
    429 {
    430     _StdIn.clearScreen();
    431     _StdIn.resetXY();
    432     _StdIn.resetScroll();
    433 }
    434 
    435 function shellMan(args)
    436 {
    437     if (args.length > 0)
    438     {
    439         var topic = args[0];
    440         switch (topic)
    441         {
    442             case "help": 
    443                 _StdIn.putText("Help displays a list of (hopefully) valid commands.");
    444                 break;
    445             default:
    446                 _StdIn.putText("No manual entry for " + args[0] + ".");
    447         }        
    448     }
    449     else
    450     {
    451         _StdIn.putText("Usage: man <topic>  Please supply a topic.");
    452     }
    453 }
    454 
    455 function shellTrace(args)
    456 {
    457     if (args.length > 0)
    458     {
    459         var setting = args[0];
    460         switch (setting)
    461         {
    462             case "on": 
    463                 if (_Trace && _SarcasticMode)
    464                 {
    465                     _StdIn.putText("Trace is already on, dumbass.");
    466                 }
    467                 else
    468                 {
    469                     _Trace = true;
    470                     _StdIn.putText("Trace ON");
    471                 }
    472                 
    473                 break;
    474             case "off": 
    475                 _Trace = false;
    476                 _StdIn.putText("Trace OFF");                
    477                 break;                
    478             default:
    479                 _StdIn.putText("Invalid arguement.  Usage: trace <on | off>.");
    480         }        
    481     }
    482     else
    483     {
    484         _StdIn.putText("Usage: trace <on | off>");
    485     }
    486 }
    487 
    488 function shellRot13(args)
    489 {
    490     if (args.length > 0)
    491     {
    492         _StdIn.putText(args[0] + " = '" + rot13(args[0]) +"'");     // Requires Utils.js for rot13() function.
    493     }
    494     else
    495     {
    496         _StdIn.putText("Usage: rot13 <string>  Please supply a string.");
    497     }
    498 }
    499 
    500 function shellPrompt(args)
    501 {
    502     if (args.length > 0)
    503     {
    504         _OsShell.promptStr = args[0];
    505     }
    506     else
    507     {
    508         _StdIn.putText("Usage: prompt <string>  Please supply a string.");
    509     }
    510 }
    511 
    512 /*
    513  * Displays the current date and time in the format: "MM/DD/YYYY HH:MM:SS"
    514  */
    515 function shellDate(args)
    516 {
    517     _StdIn.putText(Date());   
    518 }
    519 
    520 /*
    521  * Displays where you are.
    522  */
    523 function shellWhereami(args) {
    524   if (navigator.geolocation) {
    525     navigator.geolocation.getCurrentPosition(
    526       function (position) {
    527         _StdIn.putText('lat:' + position.coords.latitude + ' lng:' + position.coords.longitude);
    528       }.bind(this),
    529       function () {}.bind(this)); //failure
    530   } else {
    531     _StdIn.putText("Geolocation not found.");
    532   }
    533   return false;
    534 }
    535 
    536 // TODO: Override all data in filesystem less than 2 seconds
    537 // (when the filesystem is implemented).
    538 function shellQuickerase(args) 
    539 { 
    540     _Console.gsod();
    541 }
    542 
    543 /* 
    544  * Sets the status of the status.
    545  */
    546 function shellStatus(args)
    547 {
    548     if (args.length > 0)
    549     {
    550         var status = args.join(" ");  
    551         _Console.taskbarSetStatus(status);
    552         _Console.taskbarRefresh();
    553     }
    554     else
    555     {
    556         _StdOut.putText("Usage: status <string>  Please supply a status.");
    557     }
    558 }
    559 
    560 /*
    561  * Loads a program into a memory so it becomes a process.
    562  */
    563 function shellLoad(args)  {
    564 
    565   function getPriority() {
    566     var priority = args[0];
    567     if(priority == undefined || 
    568        !isInt(priority) || 
    569        CPU_STATE != CPU_STATE_PRIORITY.name) { 
    570 
    571       if(CPU_STATE != CPU_STATE_PRIORITY.name &&
    572          priority != undefined && 
    573          isInt(priority)) {
    574         _StdOut.putText("Scheduler not set to Priority.");
    575         _Console.advanceLine();
    576       }
    577 
    578       return 5;
    579     } else 
    580       return priority;
    581   }
    582 
    583   var hex = trim(document.getElementById(TA_PROGRAM_INPUT).
    584       value.replace(/\n/g, " "));
    585 
    586   if(isValidHex(hex)) { // in utils.js
    587     var bytes = hex.split(" ");
    588     if(bytes.length > 1) {
    589       if (bytes.length <= MAX_MEMORY_PROGRAM) {
    590         // pass the hex to kernel's memory manager
    591         var priority = getPriority();
    592         var pid = _KernelMemoryManager.load(bytes, priority);
    593         if(pid < 0)
    594           _StdOut.putText("There is no memory available.");
    595         else 
    596           _StdOut.putText("Your program has been "+
    597               "successfully loaded with PID: " + pid);
    598       } else {
    599         _StdOut.putText("Program is too large. Must be"+
    600             " less than "+MAX_MEMORY_PROGRAM+" bytes.");
    601       }
    602     } else _StdOut.putText("Input Program textarea is empty."); 
    603   } else {
    604     _StdOut.putText("Invalid program. Make sure it's"+
    605         " properly formatted hex.");
    606   }
    607 }
    608 
    609 /*
    610  * Executes a loaded process given a PID. 
    611  */
    612 function shellRun(args)  {
    613   var pid = args[0];
    614   if(pid == undefined) {
    615     _StdIn.putText('Usage: run <pid>');
    616   } else {
    617     var process = _KernelMemoryManager.processes[pid];
    618     if(process == undefined) {
    619       _StdOut.putText("No such process.");
    620     } else {
    621       if(process.state != PCB_STATE_RESIDENT)
    622         _StdOut.putText("Process cannot run.");
    623       else {
    624         _KernelReadyQueue.push(process, process.priority);
    625         process.setState(PCB_STATE_READY);
    626       }
    627     }
    628   }
    629 }
    630 
    631 /*
    632  * Runs all resident processes.
    633  */
    634 function shellRunAll(args) {
    635   var ps = _KernelMemoryManager.processes;
    636   var ran = 0;
    637   for(var i=0; i<ps.length; i++) {
    638     if(ps[i].state == PCB_STATE_RESIDENT) {
    639       _KernelReadyQueue.push(ps[i], ps[i].priority);
    640       ps[i].setState(PCB_STATE_READY);
    641       ran++;
    642     }
    643   }
    644   _StdOut.putText("Running "+ran+" processes.");
    645 }
    646 
    647 /*
    648  * Resets the entire operating system.
    649  */
    650 function shellReset(args) {
    651   simBtnReset_click(null);
    652 }
    653 
    654 /*
    655  * Sets the Round-Robin quantum.
    656  */
    657 function shellRRQuantum(args) {
    658   var newQuantum = args[0];
    659   if(newQuantum == undefined) {
    660     _StdOut.putText("Usage: rrquantum <quantum number>");
    661     _Console.advanceLine();
    662     _StdOut.putText("Current Quantum: "+RR_QUANTUM);
    663   } else if(!isInt(newQuantum.trim()))
    664     _StdOut.putText("Invalid quantum value.");
    665   else {
    666     RR_QUANTUM = newQuantum.trim();
    667     _StdOut.putText("Round-Robin Quantum set to "+RR_QUANTUM);
    668   }
    669 }
    670 
    671 /*
    672  * Shows all active processes' ID.
    673  */
    674 function shellProcesses(args) {
    675   var ps = _KernelMemoryManager.processes;
    676   _StdOut.putText("Total Active PIDs: "+ps.length);
    677   _Console.advanceLine();
    678   for(var i=0; i<ps.length; i++) {
    679     _StdOut.putText(ps[i].PID+" - "+ps[i].state);
    680     _Console.advanceLine();
    681   }
    682 }
    683 
    684 /*
    685  * Kills an active process in ready, resident 
    686  * or running mode.
    687  */
    688 function shellKill(args) {
    689   var pid = args[0];
    690   if(pid == undefined) {
    691     _StdIn.putText('Usage: kill <pid>');
    692   } else {
    693     var process = _KernelMemoryManager.processes[pid];
    694     if(process == undefined) {
    695       _StdOut.putText("No such process.");
    696     } else {
    697       if(process.state == PCB_STATE_TERMINATED)
    698         _StdOut.putText("Process is already terminated.");
    699       else {
    700         process.setState(PCB_STATE_TERMINATED);
    701       }
    702     }
    703   }
    704 }
    705 
    706 /*
    707  * Changes the current working directory.
    708  */
    709 function shellCD(args) {
    710   var fn = args[0];
    711 
    712   if(fn == undefined) {
    713     _StdOut.putText("Usage: cd <directory name>");
    714     return;
    715   }
    716 
    717   if(!krnFilesystemDriver.changeDirectory(fn))
    718     _StdOut.putText(fn+" is not a directory");
    719 }
    720 
    721 /*
    722  * Creates a new directory.
    723  */
    724 function shellCreateDirectory(args) {
    725   var fn = args[0];
    726 
    727   if(fn == undefined) {
    728     _StdOut.putText("Usage: mkdir <file name>");
    729     return;
    730   }
    731 
    732   if(krnFilesystemDriver.createDirectory(fn))
    733     _StdOut.putText(fn+" created");
    734   else 
    735     _StdOut.putText(fn+" not created");
    736 }
    737 
    738 /*
    739  * Creates a new text file.
    740  */
    741 function shellCreateFile(args) {
    742   var fn = args[0];
    743 
    744   if(fn == undefined) {
    745     _StdOut.putText("Usage: create <file name>");
    746     return;
    747   }
    748 
    749   if(krnFilesystemDriver.createTextFile(fn))
    750     _StdOut.putText(fn+" created");
    751   else 
    752     _StdOut.putText(fn+" not created");
    753 }
    754 
    755 /*
    756  * Reads a file.
    757  */
    758 function shellRead(args) {
    759   var fn = args[0];
    760 
    761   if(fn == undefined) {
    762     _StdOut.putText("Usage: read <file name>");
    763     return;
    764   }
    765 
    766   var text = krnFilesystemDriver.readTextFile(fn);
    767   if(text == undefined) 
    768     _StdOut.putText(fn+" is not a text file.");
    769   else {
    770     _StdOut.putText(text);
    771   }
    772 }
    773 
    774 /*
    775  * Writes data to a file.
    776  */
    777 function shellWrite(args) {
    778   var fn = args[0];
    779   var data = args[1];
    780   for(var i=2; i<args.length; i++)
    781     data += " "+args[i];
    782 
    783   if(fn == undefined || data == undefined) {
    784     _StdOut.putText("Usage: write <file name> <data>");
    785     return;
    786   }
    787   
    788   if(krnFilesystemDriver.writeTextFile(fn,data))
    789     _StdOut.putText(fn+" modified");
    790   else 
    791     _StdOut.putText(fn+" not modified");
    792 }
    793 
    794 /*
    795  * Deletes a file.
    796  */
    797 function shellDelete(args) {
    798   var fn = args[0];
    799 
    800   if(fn == undefined) {
    801     _StdOut.putText("Usage: delete <file name>");
    802     return;
    803   }
    804 
    805   if(krnFilesystemDriver.deleteFile(fn))
    806     _StdOut.putText(fn+" deleted");
    807   else 
    808     _StdOut.putText(fn+" not deleted");
    809 }
    810 
    811 /*
    812  * Formats the entire filesystem.
    813  */
    814 function shellFormat(args) {
    815   if(krnFilesystemDriver.format())
    816     _StdOut.putText("Format succeeded");
    817   else 
    818     _StdOut.putText("Format FAILED");
    819 }
    820 
    821 /*
    822  * Lists the files currently stored on disk.
    823  */
    824 function shellLs(args) {
    825   var files = krnFilesystemDriver.ls();
    826   for(var i=0; i < files.length; i++) {
    827     var file = files[i];
    828     var name = file.name();
    829     var type = file.type();
    830     var type_dir = file.TYPE_DIR;
    831 
    832     if(type == type_dir)
    833       _StdOut.putText("d - "+name);
    834     else
    835       _StdOut.putText("t - "+name);
    836 
    837     _Console.advanceLine();
    838   }
    839 }
    840 
    841 /*
    842  * Set cpu scheduling to rr, fcfs or priority.
    843  */
    844 function shellSetcpu(args) {
    845   function setScheduler(schedule) {
    846     var running = _KernelCPUScheduler.running;
    847     if(!running || running.state != PCB_STATE_RUNNING) {
    848       CPU_STATE = schedule;
    849       _StdOut.putText("CPU Scheduler set to "+schedule);
    850     } else
    851       _StdOut.putText("CPU Scheduler is running.");
    852   }
    853 
    854   var scheduling = args[0];
    855 
    856   if(scheduling == undefined)
    857     _StdOut.putText("Usage: setcpu <scheduler (rr, fcfs, priority)>");
    858   else {
    859     scheduling = scheduling.trim().toLowerCase();
    860     if(CPU_STATE_RR.abbr == scheduling) 
    861       setScheduler(CPU_STATE_RR.name);
    862     else if(CPU_STATE_FCFS.abbr == scheduling)
    863       setScheduler(CPU_STATE_FCFS.name);
    864     else if(CPU_STATE_PRIORITY.abbr == scheduling)
    865       setScheduler(CPU_STATE_PRIORITY.name);
    866     else 
    867       _StdOut.putText("Invalid. Values: rr, fcfs, priority");
    868   }
    869 }
    870 
    871 /*
    872  * Shows the currently running cpu scheduling.
    873  */
    874 function shellWhatcpu(args) {
    875   _StdOut.putText("CPU Scheduler set to "+CPU_STATE);
    876 }