asst3-Virtual Memory Translation/kern/syscall/runprogram.c
static
int
loadexec(char *path, vaddr_t *entrypoint, vaddr_t *stackptr)
{
	struct addrspace *newvm, *oldvm;
	struct vnode *v;
	char *newname;
	int result;

	/* new name for thread */
	newname = kstrdup(path);
	if (newname == NULL) {
		return ENOMEM;
	}

	/* open the file. */
	result = vfs_open(path, O_RDONLY, 0, &v);
	if (result) {
		kfree(newname);
		return result;
	}

	/* make a new address space. */
	newvm = as_create();
	if (newvm == NULL) {
		vfs_close(v);
		kfree(newname);
		return ENOMEM;
	}

	/* replace address spaces, and activate the new one */
	oldvm = proc_setas(newvm);
	as_activate();

 	/*
	 * Load the executable. If it fails, restore the old address
	 * space and (re-)activate it.
	 */
	result = load_elf(v, entrypoint);
	if (result) {
		vfs_close(v);
		proc_setas(oldvm);
		as_activate();
		as_destroy(newvm);
		kfree(newname);
		return result;
	}

	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(newvm, stackptr);
	if (result) {
		proc_setas(oldvm);
		as_activate();
		as_destroy(newvm);
		kfree(newname);
		return result;
        }

	/*
	 * Wipe out old address space.
	 *
	 * Note: once this is done, execv() must not fail, because there's
	 * nothing left for it to return an error to.
	 */
	if (oldvm) {
		as_destroy(oldvm);
	}

	/*
	 * Now that we know we're succeeding, change the current thread's
	 * name to reflect the new process.
	 */
	kfree(curthread->t_name);
	curthread->t_name = newname;

	return 0;
}
/*
 * Common code for execv and runprogram: loading the executable.
 */
Common code for execv and runprogram: loading the executable.
Common code for execv and runprogram : loading the executable .
static
int
loadexec(char *path, vaddr_t *entrypoint, vaddr_t *stackptr)
{
	struct addrspace *newvm, *oldvm;
	struct vnode *v;
	char *newname;
	int result;
	newname = kstrdup(path);
	if (newname == NULL) {
		return ENOMEM;
	}
	result = vfs_open(path, O_RDONLY, 0, &v);
	if (result) {
		kfree(newname);
		return result;
	}
	newvm = as_create();
	if (newvm == NULL) {
		vfs_close(v);
		kfree(newname);
		return ENOMEM;
	}
	oldvm = proc_setas(newvm);
	as_activate();
	result = load_elf(v, entrypoint);
	if (result) {
		vfs_close(v);
		proc_setas(oldvm);
		as_activate();
		as_destroy(newvm);
		kfree(newname);
		return result;
	}
	vfs_close(v);
	result = as_define_stack(newvm, stackptr);
	if (result) {
		proc_setas(oldvm);
		as_activate();
		as_destroy(newvm);
		kfree(newname);
		return result;
        }
	if (oldvm) {
		as_destroy(oldvm);
	}
	kfree(curthread->t_name);
	curthread->t_name = newname;
	return 0;
}
static int loadexec ( char * path , vaddr_t * entrypoint , vaddr_t * stackptr ) { struct addrspace * newvm , * oldvm ; struct vnode * v ; char * newname ; int result ; newname = kstrdup ( path ) ; if ( newname == NULL ) { return ENOMEM ; } result = vfs_open ( path , O_RDONLY , 0 , & v ) ; if ( result ) { kfree ( newname ) ; return result ; } newvm = as_create ( ) ; if ( newvm == NULL ) { vfs_close ( v ) ; kfree ( newname ) ; return ENOMEM ; } oldvm = proc_setas ( newvm ) ; as_activate ( ) ; result = load_elf ( v , entrypoint ) ; if ( result ) { vfs_close ( v ) ; proc_setas ( oldvm ) ; as_activate ( ) ; as_destroy ( newvm ) ; kfree ( newname ) ; return result ; } vfs_close ( v ) ; result = as_define_stack ( newvm , stackptr ) ; if ( result ) { proc_setas ( oldvm ) ; as_activate ( ) ; as_destroy ( newvm ) ; kfree ( newname ) ; return result ; } if ( oldvm ) { as_destroy ( oldvm ) ; } kfree ( curthread -> t_name ) ; curthread -> t_name = newname ; return 0 ; }
Common code for execv and runprogram: loading the executable.
Common code for execv and runprogram : loading the executable .
/* new name for thread */ /* open the file. */ /* make a new address space. */ /* replace address spaces, and activate the new one */ /*
	 * Load the executable. If it fails, restore the old address
	 * space and (re-)activate it.
	 */ /* Define the user stack in the address space */ /*
	 * Wipe out old address space.
	 *
	 * Note: once this is done, execv() must not fail, because there's
	 * nothing left for it to return an error to.
	 */ /*
	 * Now that we know we're succeeding, change the current thread's
	 * name to reflect the new process.
	 */