private int handleJoin(int pid, int status) { if (pid < 0 || status < 0) { return -1; } // get the child process from our hashmap childProcess childData; if (map.containsKey(pid)) { childData = map.get(pid); } else { return -1; } // join it childData.child.thread.join(); // remove from hashmap map.remove(pid); // write the exit # to the address status if (childData.status != -999) { byte exitStatus[] = new byte[4]; exitStatus = Lib.bytesFromInt(childData.status); int byteTransfered = writeVirtualMemory(status, exitStatus); if (byteTransfered == 4) { return 1; } else { return 0; } } return 0; }
/** * Load the executable with the specified name into this process, and prepare to pass it the * specified arguments. Opens the executable, reads its header information, and copies sections * and arguments into this process's virtual memory. * * @param name the name of the file containing the executable. * @param args the arguments to pass to the executable. * @return <tt>true</tt> if the executable was successfully loaded. */ private boolean load(String name, String[] args) { Lib.debug(dbgProcess, "UserProcess.load(\"" + name + "\")"); OpenFile executable = ThreadedKernel.fileSystem.open(name, false); if (executable == null) { Lib.debug(dbgProcess, "\topen failed"); return false; } try { coff = new Coff(executable); } catch (EOFException e) { executable.close(); Lib.debug(dbgProcess, "\tcoff load failed"); return false; } // make sure the sections are contiguous and start at page 0 numPages = 0; for (int s = 0; s < coff.getNumSections(); s++) { CoffSection section = coff.getSection(s); if (section.getFirstVPN() != numPages) { coff.close(); Lib.debug(dbgProcess, "\tfragmented executable"); return false; } numPages += section.getLength(); } // make sure the argv array will fit in one page byte[][] argv = new byte[args.length][]; int argsSize = 0; for (int i = 0; i < args.length; i++) { argv[i] = args[i].getBytes(); // 4 bytes for argv[] pointer; then string plus one for null byte argsSize += 4 + argv[i].length + 1; } if (argsSize > pageSize) { coff.close(); Lib.debug(dbgProcess, "\targuments too long"); return false; } // program counter initially points at the program entry point initialPC = coff.getEntryPoint(); // next comes the stack; stack pointer initially points to top of it numPages += stackPages; initialSP = numPages * pageSize; // and finally reserve 1 page for arguments numPages++; if (!loadSections()) return false; // store arguments in last page int entryOffset = (numPages - 1) * pageSize; int stringOffset = entryOffset + args.length * 4; this.argc = args.length; this.argv = entryOffset; for (int i = 0; i < argv.length; i++) { byte[] stringOffsetBytes = Lib.bytesFromInt(stringOffset); Lib.assertTrue(writeVirtualMemory(entryOffset, stringOffsetBytes) == 4); entryOffset += 4; Lib.assertTrue(writeVirtualMemory(stringOffset, argv[i]) == argv[i].length); stringOffset += argv[i].length; Lib.assertTrue(writeVirtualMemory(stringOffset, new byte[] {0}) == 1); stringOffset += 1; } return true; }