/** * Handle a syscall exception. Called by <tt>handleException()</tt>. The <i>syscall</i> argument * identifies which syscall the user executed: * * <table> * <tr><td>syscall#</td><td>syscall prototype</td></tr> * <tr><td>0</td><td><tt>void halt();</tt></td></tr> * <tr><td>1</td><td><tt>void exit(int status);</tt></td></tr> * <tr><td>2</td><td><tt>int exec(char *name, int argc, char **argv); * </tt></td></tr> * <tr><td>3</td><td><tt>int join(int pid, int *status);</tt></td></tr> * <tr><td>4</td><td><tt>int creat(char *name);</tt></td></tr> * <tr><td>5</td><td><tt>int open(char *name);</tt></td></tr> * <tr><td>6</td><td><tt>int read(int fd, char *buffer, int size); * </tt></td></tr> * <tr><td>7</td><td><tt>int write(int fd, char *buffer, int size); * </tt></td></tr> * <tr><td>8</td><td><tt>int close(int fd);</tt></td></tr> * <tr><td>9</td><td><tt>int unlink(char *name);</tt></td></tr> * </table> * * @param syscall the syscall number. * @param a0 the first syscall argument. * @param a1 the second syscall argument. * @param a2 the third syscall argument. * @param a3 the fourth syscall argument. * @return the value to be returned to the user. */ public int handleSyscall(int syscall, int a0, int a1, int a2, int a3) { switch (syscall) { case syscallHalt: return handleHalt(); case syscallCreate: return handleCreate(a0); case syscallOpen: return handleOpen(a0); case syscallRead: return handleRead(a0, a1, a2); case syscallWrite: return handleWrite(a0, a1, a2); case syscallClose: return handleClose(a0); case syscallUnlink: return handleUnlink(a0); case syscallExit: handleExit(a0); case syscallExec: return handleExec(a0, a1, a2); case syscallJoin: return handleJoin(a0, a1); default: Lib.debug(dbgProcess, "Unknown syscall " + syscall); Lib.assertNotReached("Unknown system call!"); } return 0; }
/** Handle the halt() system call. */ private int handleHalt() { if (this.process_id != ROOT) { return 0; } Machine.halt(); Lib.assertNotReached("Machine.halt() did not halt machine!"); return 0; }
private void handleExit(int status) { if (myChildProcess != null) { myChildProcess.status = status; } // close all the opened files for (int i = 0; i < 16; i++) { handleClose(i); } // part2 implemented this.unloadSections(); if (this.process_id == ROOT) { Kernel.kernel.terminate(); } else { KThread.finish(); Lib.assertNotReached(); } }
/** * Handle a user exception. Called by <tt>UserKernel.exceptionHandler()</tt>. The <i>cause</i> * argument identifies which exception occurred; see the <tt>Processor.exceptionZZZ</tt> * constants. * * @param cause the user exception that occurred. */ public void handleException(int cause) { Processor processor = Machine.processor(); switch (cause) { case Processor.exceptionSyscall: int result = handleSyscall( processor.readRegister(Processor.regV0), processor.readRegister(Processor.regA0), processor.readRegister(Processor.regA1), processor.readRegister(Processor.regA2), processor.readRegister(Processor.regA3)); processor.writeRegister(Processor.regV0, result); processor.advancePC(); break; default: Lib.debug(dbgProcess, "Unexpected exception: " + Processor.exceptionNames[cause]); handleExit(-1); Lib.assertNotReached("Unexpected exception"); } }