/* * Get information about the running processes * Params: * state->ebx - pointer to user memory containing an array of * Process_Info structs * state->ecx - length of the passed in array in memory * Returns: -1 on failure * 0 if size of user memory too small * N the number of entries in the table, on success */ static int Sys_PS(struct Interrupt_State* state) { struct Process_Info procInfo[50] = {'\0', }; Dump_All_Thread_List(procInfo); Copy_To_User(state->ebx, procInfo, state->ecx*sizeof(struct Process_Info)); return 0; //TODO("Sys_PS system call"); }
/* * Spawn a user process. * Params: * program - the full path of the program executable file * command - the command, including name of program and arguments * pThread - reference to Kernel_Thread pointer where a pointer to * the newly created user mode thread (process) should be * stored * Returns: * The process id (pid) of the new process, or an error code * if the process couldn't be created. Note that this function * should return ENOTFOUND if the reason for failure is that * the executable file doesn't exist. */ int Spawn(const char *program, const char *command, struct Kernel_Thread **pThread, bool detached) { /* * Hints: * - Call Read_Fully() to load the entire executable into a memory buffer * - Call Parse_ELF_Executable() to verify that the executable is * valid, and to populate an Exe_Format data structure describing * how the executable should be loaded * - Call Load_User_Program() to create a User_Context with the loaded * program * - Call Start_User_Thread() with the new User_Context * * If all goes well, store the pointer to the new thread in * pThread and return 0. Otherwise, return an error code. */ // TODO("Spawn a process by reading an executable from a filesystem"); int error = 0; char *exeFileData = 0; ulong_t exeFileLength; struct Exe_Format exeFormat; struct User_Context *userContext = 0; // userContext will become (*pThread)->userContext, through function Attach_User_Context() if everything is successful if(USERDEBUG) Print("Reading %s %s\n", program, command); if((error = Read_Fully(program, (void**) &exeFileData, &exeFileLength)) != 0) { if(USERDEBUG) Print("Read_Fully failed to read %s from disk\n", program); Free(exeFileData); return error; } if(USERDEBUG) Print("Read_Fully OK\n"); if((error = Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat)) != 0) { if(USERDEBUG) Print("Parse_ELF_Executable failed\n"); Free(exeFileData); return error; } if(USERDEBUG) Print("Parse_ELF_Executable OK\n"); if((error = Load_User_Program(exeFileData, exeFileLength, &exeFormat, command, &userContext)) != 0) { if(USERDEBUG) Print("Load_User_Program failed\n"); Free(exeFileData); Free(userContext); return error; } if(USERDEBUG) Print("Load_User_Program for program: %s OK\n", program); /*deleting local copy of exeFileData because Load_User_Program was successfully*/ Free(exeFileData); (*pThread) = Start_User_Thread(userContext, detached); if(!(*pThread)) return ENOMEM; if(USERDEBUG) { Print("Spawn complete\nDump_All_Thread_List:\n"); Dump_All_Thread_List(); } return (*pThread)->pid; }