Exemplo n.º 1
0
/*
 * 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)
{
    /*
     * 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.
     */
    /* Por Victor Rosales */
    char *exeFileData = 0;
    ulong_t exeFileLength = 0;
    struct Exe_Format exeFormat;
    struct User_Context *userContext = NULL;
    struct Kernel_Thread *process = NULL;
    int ret = 0;

    ret = Read_Fully(program, (void**) &exeFileData, &exeFileLength);
    if (ret != 0) {
        ret = ENOTFOUND;
        goto error;
    }

    ret = Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat);
    if (ret != 0) {
        ret = ENOEXEC;
        goto error;
    }

    ret = Load_User_Program(exeFileData, exeFileLength, &exeFormat,
                            command, &userContext);
    if (ret != 0) {
        ret = -1;
        goto error;
    }

    process = Start_User_Thread(userContext, false);
    if (process == NULL) {
        ret = -1;
        goto error;
    }

    *pThread = process;

    ret =(*pThread)->pid;

error:
    if (exeFileData)
        Free(exeFileData);

    exeFileData = 0;
 
    return ret;
}
Exemplo n.º 2
0
/*
 * 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)
{
	/*
     * 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.
     */


	char *exeFileData = 0;
	ulong_t exeFileLength;
	struct Exe_Format exeFormat;
	struct User_Context* pUserContext;

	if (userdebug)
	  {
		Print("Reading %s...\n", program);
	  }
	
	if (Read_Fully(program, (void**) &exeFileData, &exeFileLength) != 0)
	  {
		Print("Read_Fully failed to read %s from disk\n", program);
		return -1;
	  }

	if (userdebug)
	  {  
		Print("Read_Fully OK\n");
	  }
	
	if (Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat) != 0)
	  {
		Print("Parse_ELF_Executable failed\n");
		return -1;
	  }

	if (userdebug)
    { 
      Print("Parse_ELF_Executable OK\n");
    }	 

	Load_User_Program(exeFileData, exeFileLength, &exeFormat, command,
    (struct User_Context **)&pUserContext);

	*pThread = Start_User_Thread(pUserContext, false);

	return (*pThread)->pid;
}
Exemplo n.º 3
0
/*
 * 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:
 *   Zero 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 background) {
    int rc;
    char *exeFileData = 0;
    ulong_t exeFileLength;
    struct User_Context *userContext = 0;
    struct Kernel_Thread *process = 0;
    struct Exe_Format exeFormat;

    /*
     * Load the executable file data, parse ELF headers,
     * and load code and data segments into user memory.
     */

    if ((rc = Read_Fully(program, (void **)&exeFileData, &exeFileLength)) != 0
        || (rc =
            Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat)) != 0
        || (rc =
            Load_User_Program(exeFileData, exeFileLength, &exeFormat, command,
                              &userContext)) != 0)
        goto fail;

    /*
     * User program has been loaded, so we can free the
     * executable file data now.
     */
    Free(exeFileData);
    exeFileData = 0;
    strncpy(userContext->name, program, MAX_PROC_NAME_SZB);
    userContext->name[MAX_PROC_NAME_SZB - 1] = '\0';
    /* Start the process! */
    
    process = Start_User_Thread(userContext, background);
    if (process != 0) {
        /* Return Kernel_Thread pointer */
        *pThread = process;
    } else
        rc = ENOMEM;
       
    return rc;

  fail:
    if (exeFileData != 0)
        Free(exeFileData);
    if (userContext != 0)
        Destroy_User_Context(userContext);

    return rc;
}
Exemplo n.º 4
0
/*
 * 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;
}
Exemplo n.º 5
0
/*
 * 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)
{
    /*
     * 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");
     char *exeFileData = 0;
     ulong_t exeFileLength;
     struct Exe_Format exeFormat;
     struct User_Context * pUserContext = NULL;
     struct Kernel_Thread* pkthread;
     int rc;

     if (lprogdebug)
     {
        Print("Reading %s...\n", program);
     }

     if ( (rc = Read_Fully(program, (void**) &exeFileData, &exeFileLength)) != 0)
     {
        Print("Read_Fully failed to read %s from disk\n", program);
        goto fail;
     }

     if (lprogdebug)
     {  
       Print("Read_Fully OK\n");
     }

  if ((rc = Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat)) != 0)
    {
      Print("Parse_ELF_Executable failed\n");
      goto fail;
    }

  if (lprogdebug)
    { 
      Print("Parse_ELF_Executable OK\n");
    }


  if ( (rc = Load_User_Program(exeFileData, exeFileLength,
		&exeFormat, command,
		&pUserContext)) != 0)
    {
      Print("Load_User_Program failed\n");
      goto fail;
    }

  if ((pkthread = Start_User_Thread(pUserContext, false)) == NULL) //ERROR detached should be false
  {
  	Print("Start_User_Thread Failed!\n");
	rc = -1;
	goto fail;
  }
  
    /*
     * User program has been loaded, so we can free the
     * executable file data now.
     */
    Free(exeFileData);
    exeFileData = 0;

  /* If we arrived here, everything was fine and the program exited */
  //Print("If you see this you're happy\n");
  *pThread = pkthread;
  if(pThread == NULL)
	Print("wrong!\n");

  return pkthread->pid;
  // Exit(0); as this is not a thread, we don't exit but return.


fail:

    /* We failed; release any allocated memory */
    //if(Interrupts_Enabled())
    	Disable_Interrupts();

    if(pUserContext != NULL && pUserContext->memory != NULL)
        Free(pUserContext->memory);

    Enable_Interrupts();

    return rc;
}