示例#1
0
文件: runprogram.c 项目: mellwa/os
int
runprogram(char *progname)
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);

	/* Create a new address space. */
	#if OPT_A3
	as = as_create(progname);
	#else
	as = as_create();
	#endif
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

	/* Warp to user mode. */
	enter_new_process(0 /*argc*/, NULL /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#2
0
文件: runprogram.c 项目: JayP16/OS161
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}
	curthread->t_filetable = filetable_create();
	if(curthread->t_filetable == NULL){
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	/* Warp to user mode. */
	enter_new_process(0 /*argc*/, NULL /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#3
0
int execv(const char *program, char **args)
{
	//    kprintf("\n\n execv testing \n\n") ;
    	if (program == NULL )
        {
		return EFAULT ;
	}
	//char * kernel_pgm = (char *)kmalloc(sizeof(char *)) ;
	char * kernel_pgm = (char *)kmalloc(__PATH_MAX) ;
	
	size_t bytes_copied  ;
	int result = copyinstr((const userptr_t)program,kernel_pgm,__PATH_MAX,&bytes_copied) ;

	if (result )
	{
		return result ;
	}

	if (strlen(kernel_pgm) == 0)
	{
		return EINVAL ;
	}
	if (strlen(kernel_pgm) >= __PATH_MAX)
	{
		return ENAMETOOLONG ;
	}
	int argc = 0 ;
	if (args == NULL)
	{
		return EFAULT ;
	}
	char *temp1 = (char *)kmalloc(ARG_MAX*sizeof(char)) ;
        result = copyinstr((const userptr_t)args,temp1,ARG_MAX*sizeof(char),&bytes_copied) ;
        if(result){
                return result;
        }
        kfree(temp1);
    while(args[argc]!=NULL)                                                 //while (true)
    {
     	char *temp = (char *)kmalloc(ARG_MAX*sizeof(char)) ;
        result = copyinstr((const userptr_t)args[argc],temp,ARG_MAX*sizeof(char),&bytes_copied) ;
        if (result)
        	{
            	kfree(temp);
                return EFAULT ;//break ;
            }
            argc++ ;
            kfree(temp) ;
        }
	char **temp = (char **)kmalloc(argc*sizeof(char *)) ;
	
	int i = 0 ;
	while(i<argc)
	{
		temp[i] = (char *)kmalloc(ARG_MAX*sizeof(char)) ;
		result = copyinstr((const userptr_t)args[i],temp[i],ARG_MAX*sizeof(char),&bytes_copied) ;
		if (result)
		{
			return result ;
		}
		i++ ;
	}
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	result = vfs_open(kernel_pgm, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	struct addrspace *addrspace_copy=curthread->t_addrspace;
	if(curthread->t_addrspace != NULL){
		as_destroy(curthread->t_addrspace);
		curthread->t_addrspace = NULL;
	}
	//struct addrspace *addrspace_copy=curthread->t_addrspace;
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		curthread->t_addrspace = addrspace_copy;
		return ENOMEM;
	}
	as_activate(curthread->t_addrspace);
	result = load_elf(v, &entrypoint);
	if (result) {
		vfs_close(v);
		return result;
	}
	vfs_close(v);
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		return result;
	}
	i = i -1 ;
	vaddr_t index[25] ;
	int k = 0 ;
	while(i>= 0)
	{
		int length = strlen(temp[i]) ;
		int num0 = (4 - (length % 4)) ;
		int j = 0 ;
		char *temp1 = (char *)kmalloc((length+num0)*sizeof(char)) ;
		strcpy(temp1,temp[i]) ;
		while(j<num0)
		{
			strcat(temp1,"\0") ;
			j++ ;
		}
		stackptr = stackptr - ((length+num0)*sizeof(char)) ;
		result = copyoutstr(temp1,(userptr_t) stackptr,(length+num0)*sizeof(char),&bytes_copied) ;
		if (result)
		{
			return result ;
		}
		index[k] = (vaddr_t )stackptr;
		k++ ;
		i-- ;
		kfree(temp1) ;
	}
	i = 0 ;
	stackptr = stackptr - sizeof(int) ;
	stackptr = stackptr - sizeof(int) ;
	k-- ;
	while(i<=k)
	{
		result = copyout(&index[i],(userptr_t) stackptr,sizeof(int)) ;
		if (result)
		{
			return result ;
		}
		i++ ;
		if (i<=k){
			stackptr = stackptr - sizeof(int) ;
		}
	}
	kfree(temp) ;
	kfree(kernel_pgm) ;
	enter_new_process(argc,(userptr_t) stackptr , stackptr, entrypoint);
	panic("enter_new_process returned\n");
	return EINVAL;
}																																																																																																    
示例#4
0
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char **args, int argc)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	// Variables for argument passing
	int i, pad;
	size_t offset, get;
	userptr_t userdest;

    size_t got[argc];
    userptr_t user_argv[argc];

    // Count length of each arg
    i = 0;
    for (i=0; i<argc; i++){
    	got[i] = strlen(args[i]) + 1; // Need +1 to account for /0
    }

    /* We enforce that the kernel is only allowed to start ONE user process
     * directly through runprogram with PID_MIN as its pid. Thereafter any
     * new user process needs to be forked from existing ones.
     */
	KASSERT(process_table[PID_MIN] == NULL);
	curthread->pid = PID_MIN;

	stdio_init();

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

    // Copy args to new addrspace
    offset = 0;
    for (i=argc-1; i>-1; i--){
        pad = (4 - (got[i]%4) ) % 4; // Word align
        offset += pad;
        offset += got[i];

        user_argv[i] = (userptr_t)(stackptr - offset);

        result = copyoutstr((const char*)args[i], user_argv[i], got[i], &get);
        if (result){
            return result;
        }
    }

    // Copy pointers to argv
    userdest = user_argv[0] - 4 * (argc+1);
    stackptr = (vaddr_t)userdest; // Set stack pointer
    for (i=0; i<argc; i++){
        result = copyout((const void *)&user_argv[i], userdest, 4);
        if (result){
        	return result;
        }
        userdest += 4;
    }

	/* Warp to user mode. */
	enter_new_process(argc, (userptr_t)stackptr, stackptr, entrypoint);

	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#5
0
int sys_execv(char* progname, char** args, int *retval, bool iskernel) {
	int result;
	int *args_len;
	size_t len;
	size_t total_len = 0;
	char *temp;
	char **kern_args;
	int nargs = 0;
	userptr_t *usr_argv = NULL;
	char *kern_progname = kmalloc(PATH_MAX);
	args_len = kmalloc(sizeof(int) * ARG_MAX);
	temp = kmalloc(sizeof(char) * ARG_MAX);

	if (kern_progname == NULL || args_len == NULL || temp == NULL){
		*retval = -1;
		return ENOMEM;
	}

	if (args == NULL || progname == NULL) {
		*retval = -1;
		return EFAULT;
	}

	if (!iskernel) {
		result = copyinstr((userptr_t)args, temp, ARG_MAX, &len);
		if (result) {
			*retval = -1;
			return result;
		}
	}

	// Figure out nargs, and the length for each arg string
	while(args[nargs] != NULL) {
		if (iskernel) {
			len = strlen(args[nargs]) + 1;
			if (len == 1) {
				nargs--;
				break;
			}
			strcpy(temp, args[nargs]);
		} else {
			result = copyinstr((userptr_t)args[nargs], temp, ARG_MAX, &len);
			if (result) {
				*retval = -1;
				return result;
			}
		}
		args_len[nargs] = len;
		total_len += len;
		nargs += 1;
	}
	kfree(temp);

	if (total_len > ARG_MAX) {
		*retval = -1;
		return E2BIG;
	}

	kern_args = kmalloc(sizeof(char*) * nargs);

	// Go through args and copy everything over to kern_args using copyinstr
	for (int i = 0; i < nargs; i++) {
		kern_args[i] = kmalloc(sizeof(char) * args_len[i]);
		if (kern_args[i] == NULL) {
			*retval = -1;
			return ENOMEM;
		}

		if (iskernel) {
			strcpy(kern_args[i], args[i]);
			len = strlen(kern_args[i]);
		} else {
			copyinstr((userptr_t)args[i], kern_args[i], ARG_MAX, NULL);
		}
	}

	// This is from runprogram 
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;


	if (iskernel) {
		strcpy(kern_progname, progname);
		len = strlen(kern_progname);
	} else {
		result = copyinstr((userptr_t)progname, kern_progname, PATH_MAX, NULL);
	}

	if (*kern_progname == 0) {
		*retval = -1;
		return EISDIR;
	}
	if (result) {
		kfree(kern_progname);
		*retval = -1;
		return result;
	}

	/* Open the file. */
	result = vfs_open(kern_progname, O_RDONLY, 0, &v);
	if (result) {
		*retval = -1;
		return result;
	}

	// Blow up the current addrspace. TODO, this may be problematic
	if (!iskernel) {
		as_destroy(curproc->p_addrspace);
		curproc->p_addrspace = NULL;
	}

	/* We should be a new process. */
	KASSERT(proc_getas() == NULL);

	/* Create a new address space. */
	as = as_create();
	if (as == NULL) {
		vfs_close(v);
		*retval = -1;
		return ENOMEM;
	}

	/* Switch to it and activate it. */
	proc_setas(as);
	as_activate();

	/* Intialize file table, not needed for execv */
	if (iskernel)
		filetable_init();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		*retval = -1;
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		*retval = -1;
		return result;
	}

	// Clear space for arg pointers +1 for NULL terminator
	stackptr -= (sizeof(char*)) * (nargs + 1);

	// Convenience method for indexing
	usr_argv = (userptr_t*)stackptr;

	for(int i = 0; i < nargs; i++ ) {
		// Clear out space for an arg string
		stackptr -= sizeof(char) * (strlen(kern_args[i]) + 1);
		// Assign the string's pointer to usr_argv
		usr_argv[i] = (userptr_t)stackptr;
		// Copy over string
		copyout(kern_args[i], usr_argv[i],
			sizeof(char) * (strlen(kern_args[i]) + 1));
	}

	// NULL terminate usr_argv
	usr_argv[nargs] = NULL;

	// Free memory
	for(int i = 0; i < nargs; i++) {
		kfree(kern_args[i]);
	}
	kfree(kern_args);

	/* Warp to user mode. */
	enter_new_process(nargs /*argc*/, (userptr_t)usr_argv /*userspace addr of argv*/,
			  NULL /*userspace addr of environment*/,
			  stackptr, entrypoint);

	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#6
0
文件: runprogram.c 项目: gapry/os161
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, int argc, char** args)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	/* Initialize an array of pointers that stores the pointer to the
	 * string arguments in the user stack */
	char** argv = (char **)kmalloc((argc + 1) * sizeof(char*));
	if (argv == NULL) {
		return ENOMEM;
	}
	argv[argc] = 0;

	int i;
	size_t actual;
	int total = 0;

	/* Copy string arguments from kernel memory onto the user stack,
	 * and store the user pointer to the argument in argv */
	for (i = argc - 1; i >= 0; i--) {
		int len = strlen(args[i]) + 1;
		total = total + len;
		stackptr = stackptr - len;
		copyoutstr(args[i], (userptr_t)stackptr, len, &actual);
		argv[i] = (char *)stackptr;
	}

	/* Add any necessary padding to the user stack */
	int padding = 4 - (total % 4);
	if (padding) {
		stackptr = stackptr - padding;
	}

	/* Copy the array of user pointers argv onto the user stack  */
	for (i = argc; i >= 0; i--) {
		stackptr = stackptr - 4;
		copyout(&argv[i], (userptr_t)stackptr, 4);
	}

	kfree(argv);

	/* Warp to user mode. */
	enter_new_process(argc, (userptr_t)stackptr /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#7
0
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char **args, unsigned int nargs)
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

        int argc = nargs;
        char **argv = (char **)kmalloc((argc + 1) * sizeof(char *));
        if(argv == NULL)
        {
            return ENOMEM;
        }

        for(int i = 0; i < argc; ++i)
        {
            argv[i] = args[i];
        }
        argv[argc] = NULL;
       
       
	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);

	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

        /*------copy args to user stack-----------*/
        
        vaddr_t *argPtrs = (vaddr_t *)kmalloc((argc + 1) * sizeof(vaddr_t));
        if(argPtrs == NULL)
        {
            for(int i = 0; i < argc; ++i)
            {
                kfree(argv[i]);
            }
            kfree(argv);
            as_deactivate();
            as = curproc_setas(NULL);
            as_destroy(as);
            return ENOMEM;
        }
        
        for(int i = argc-1; i >= 0; --i)
        {
            //arg length with null
            size_t curArgLen = strlen(argv[i]) + 1;
            
            size_t argLen = ROUNDUP(curArgLen,4);
            
            stackptr -= (argLen * sizeof(char));
            
            //kprintf("copying arg: %s to addr: %p\n", temp, (void *)stackptr);
            
            //copy to stack
            result = copyout((void *) argv[i], (userptr_t)stackptr, curArgLen);
            if(result)
            {
                kfree(argPtrs);
                for(int i = 0; i < argc; ++i)
                {
                    kfree(argv[i]);
                }
                kfree(argv);
                as_deactivate();
                as = curproc_setas(NULL);
                as_destroy(as);
                return result;
            }
            
            argPtrs[i] = stackptr;        
        }    
        
        argPtrs[argc] = (vaddr_t)NULL;
        
        //copy arg pointers
        for(int i = argc; i >= 0; --i)
        {
            stackptr -= sizeof(vaddr_t);
            result = copyout((void *) &argPtrs[i], ((userptr_t)stackptr),sizeof(vaddr_t));
            if(result)
            {
                kfree(argPtrs);
                for(int i = 0; i < argc; ++i)
                {
                    kfree(argv[i]);
                }
                kfree(argv);
                as_deactivate();
                as = curproc_setas(NULL);
                as_destroy(as);
                return result;
            }
        }
        
        
        kfree(argPtrs);
        
        
        
        
        vaddr_t baseAddress = USERSTACK;
        
        vaddr_t argvPtr = stackptr;
        
        vaddr_t offset = ROUNDUP(USERSTACK - stackptr,8);
        
        stackptr = baseAddress - offset;
        
/*
        for(vaddr_t i = baseAddress; i >= stackptr; --i)
        {
            char *temp;
            temp = (char *)i;
            //kprintf("%p: %c\n",(void *)i,*temp);
            
            kprintf("%p: %x\n", (void *)i, *temp & 0xff);
        }
*/
        
        
        /*-done-copy args to user stack-----------*/
        
	/* Warp to user mode. */
	enter_new_process(argc /*argc*/, (userptr_t)argvPtr /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#8
0
文件: execv.c 项目: script3r/os161
int	
sys_execv( userptr_t upname, userptr_t uargs ) {
	struct addrspace		*as_new = NULL;
	struct addrspace		*as_old = NULL;
	struct vnode			*vn = NULL;
	vaddr_t				entry_ptr;
	vaddr_t				stack_ptr;
	int				err;
	char				kpname[MAX_PROG_NAME];
	int				nargs;
	int				buflen;

	KASSERT( curthread != NULL );
	KASSERT( curthread->td_proc != NULL );
	
	(void)uargs;
	
	//lock the execv args
	lock_acquire( lk_exec );

	//copy the old addrspace just in case.
	as_old = curthread->t_addrspace;

	//copyin the program name.
	err = copyinstr( upname, kpname, sizeof( kpname ), NULL );
	if( err ) {
		lock_release( lk_exec );
		return err;
	}
	
	//try to open the given executable.
	err = vfs_open( kpname, O_RDONLY, 0, &vn );
	if( err ) {
		lock_release( lk_exec );
		return err;
	}

	//copy the arguments into the kernel buffer.
	err = copy_args( uargs, &nargs, &buflen );
	if( err ) {
		lock_release( lk_exec );
		vfs_close( vn );
		return err;
	}

	//create the new addrspace.
	as_new = as_create();
	if( as_new == NULL ) {
		lock_release( lk_exec );
		vfs_close( vn );
		return ENOMEM;
	}
	
	//activate the new addrspace.
	as_activate( as_new );

	//temporarily switch the addrspaces.
	curthread->t_addrspace = as_new;

	//load the elf executable.
	err = load_elf( vn, &entry_ptr );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );
	
		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}

	//create a stack for the new addrspace.
	err = as_define_stack( as_new, &stack_ptr );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );

		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}
	
	//adjust the stackptr to reflect the change
	stack_ptr -= buflen;
	err = adjust_kargbuf( nargs, stack_ptr );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );

		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}

	//copy the arguments into the new user stack.
	err = copyout( kargbuf, (userptr_t)stack_ptr, buflen );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );
		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}

	//reelase lk_exec
	lock_release( lk_exec );

	//no need for it anymore.
	vfs_close( vn );

	//we are good to go.
	as_destroy( as_old );
	
	//off we go to userland.
	enter_new_process( nargs-1, (userptr_t)stack_ptr, stack_ptr, entry_ptr );
	
	panic( "execv: we should not be here." );
	return EINVAL;
}
示例#9
0
int sys_execv(char* program, char** args) {
	int result;

	char name[strlen(program) + 1];
	result = copyin((userptr_t) program,
				name, (strlen(program) + 1) * sizeof(char));
	//kprintf("%s", name);

	int len_arg = 0;
	while(args[len_arg] != NULL) {
		len_arg++;
	}

	int length_every_arg[len_arg];
	for(int i = 0; i < len_arg; i++) {
		length_every_arg[i] = strlen(args[i]);
	}

	char* kern_args[len_arg];
	for(int i = 0; i < len_arg; i++) {
		kern_args[i] = kmalloc(sizeof(char) * length_every_arg[i] + 1);
		copyin((const_userptr_t)args[i], kern_args[i],
              (length_every_arg[i] + 1) * sizeof(char));
	}
/*
	for(int i = 0; i < len_arg; i++) {
		kprintf("{ _%d__%p__%p_",strlen(kern_args[i]), kern_args[i],args[i]);
		kprintf("%s", kern_args[i]);
		kprintf("}\n");
	}
*/
/////////////////////////////////////////////////////
// this is "copied" from runprogram
  	struct addrspace* old_as;
	struct vnode* v;
	vaddr_t entrypoint, stackptr;

	result = vfs_open(program, O_RDONLY, 0, &v);
	if(result) {
		return result;
	}

	as_deactivate();
	old_as = curproc_setas(NULL);
	as_destroy(old_as);

	struct addrspace* new_as = as_create();
	if(new_as == NULL) {
		vfs_close(v);
		return ENOMEM;
	}
	curproc_setas(new_as);
	as_activate();

	result = load_elf(v, &entrypoint);
	if(result) {
		vfs_close(v);
		return result;
	}

	vfs_close(v);
	
	result = as_define_stack(new_as, &stackptr);
	if(result) {
		return result;
	}
//////////////////////////////////////////////////////////
// kern_args
// the addr of stackptr is 0x8000 0000
	vaddr_t argv = stackptr;
	for(int i = 0; i < len_arg + 1; i++) {
		argv = argv - 4;
	}
   
	vaddr_t start = argv;
	vaddr_t temp = argv;

	copyout(NULL, (userptr_t)(stackptr - 4), 4);
	//starts from 1, because argv[0] is reserved for the program name
	for(int i = 0; i < len_arg; i++) {
		//question? why do I have to add 2
		int m = sizeof(char) * (strlen(kern_args[i]) + 1);
	//	kprintf("the value of m -> %d\n", m);
		argv = argv - m;
		copyout(kern_args[i], (userptr_t)argv, m);
	//	kprintf("***(%d)%s(%p)\n***", m, (char* )argv, (void *) argv);
		copyout(&argv, (userptr_t)temp, sizeof(char* ));
		temp = temp + 4;
	}
	
	for(int i = 0; i < len_arg; i++) {
		kfree(kern_args[i]);
	}
	
	while(argv % 8 != 0) {argv--;}
	 
	enter_new_process(len_arg, (userptr_t)start, (vaddr_t) argv, entrypoint);

//	enter_new_process(0, NULL, stackptr, entrypoint);
	panic("enter_new_process returned");
	return EINVAL;
}
示例#10
0
int
sys_execv(char *progname, char **args, int *err) {

    struct addrspace *as;
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    int result;

    /* Validations */
    if (progname == NULL) {
        *err = EFAULT;
        return -1;
    }

    if (args == NULL || (int *)args == (int *)0x40000000 || (int *)args == (int *)0x80000000) {
        *err = EFAULT;
        return -1;
    }

    /* Count number of arguments and total size of input */
    int args_count = 0;
    for (;args_count < ARG_MAX && args[args_count] != NULL; args_count++);

    if (args_count > ARG_MAX) {
        *err = E2BIG;
        return -1;
    }

    /* Copy File name */
    char *progname_copy = (char *) kmalloc(sizeof(char) * NAME_MAX);
    size_t actual = 0;
    result = copyinstr((userptr_t)progname, progname_copy, NAME_MAX, &actual);

    if (result) {
        kfree(progname_copy);
        *err = result;
        return -1;
    }

    if (strlen(progname_copy) == 0) {
        kfree(progname_copy);
        *err = EINVAL;
        return -1;
    }

    /* Allocate Kernel Memory for arguments */
    char **args_copy = (char **) kmalloc(sizeof(char *) * args_count);

    int c_args_count = 0,
            arg_size = 0,
            padded_size = 0;

    for (;c_args_count < args_count; c_args_count++) {
        if ((int *)args[c_args_count] == (int *)0x40000000 || (int *)args[c_args_count] == (int *)0x80000000) {
            kfree(progname_copy);
            *err = EFAULT;
            return -1;
        }
    }

    c_args_count = 0;
    /* Calculate total length accounting for padding */
    for (;c_args_count < args_count; c_args_count++) {
        arg_size = strlen(args[c_args_count]) + 1;

        args_copy[c_args_count] = (char *) kmalloc(sizeof(char) * arg_size);
        copyinstr((userptr_t)args[c_args_count], args_copy[c_args_count], arg_size, &actual);

        padded_size += arg_size;
        if (padded_size % 4) {
            padded_size += (4 - (padded_size % 4)) % 4;
        }
    }

    /* Open the file. */
    result = vfs_open(progname_copy, O_RDONLY, 0, &v);
    if (result) {
        kfree(progname_copy);
        *err = result;
        return -1;
    }

    /* Destroy the current process's address space to create a new one. */
    as = curproc->p_addrspace;
    curproc->p_addrspace = NULL;

    as_destroy(as);

    /* We should be a new process. */
    KASSERT(proc_getas() == NULL);

    /* Create a new address space. */
    as = as_create();
    if (as == NULL) {
        kfree(progname_copy);
        vfs_close(v);
        *err = ENOMEM;
        return -1;
    }

    /* Switch to it and activate it. */
    proc_setas(as);
    as_activate();

    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
        /* p_addrspace will go away when curproc is destroyed */
        kfree(progname_copy);
        vfs_close(v);
        *err = result;
        return -1;
    }

    /* Done with the file now. */
    vfs_close(v);

    /* Define the user stack in the address space */
    result = as_define_stack(as, &stackptr);
    if (result) {
        /* p_addrspace will go away when curproc is destroyed */
        kfree(progname_copy);
        *err = result;
        return -1;
    }

    stackptr -= padded_size;
    char **arg_address = (char **) kmalloc(sizeof(char *) * args_count + 1);

    /* Copy arguments into user stack */
    for(int i = 0; i < args_count; i++) {
        arg_size = strlen(args_copy[i]) + 1;

        if (arg_size % 4) {
            arg_size += (4 - arg_size % 4) % 4;
        }

        /* Store address of arguments */
        arg_address[i] = (char *)stackptr;

        copyoutstr(args_copy[i], (userptr_t)stackptr, arg_size, &actual);
        stackptr += arg_size;
    }

    /* Add Null Pointer at the end */
    arg_address[args_count] = 0;

    stackptr -= padded_size;
    stackptr -= (args_count + 1) * sizeof(char *);

    /* Copy address locations into user stack*/
    for (int i = 0; i < args_count + 1; i++) {
        copyout((arg_address + i), (userptr_t)stackptr, sizeof(char *));
        stackptr += sizeof(char *);
    }

    /* Reset pointer to start of the stack */
    stackptr -= ((args_count + 1) * sizeof(char *));

    kfree(progname_copy);

    c_args_count = 0;
    for (;c_args_count < args_count; c_args_count++) {
        kfree(args_copy[c_args_count]);
    }

    kfree(args_copy);
    kfree(arg_address);

    /* Warp to user mode. */
    enter_new_process(args_count /*argc*/, (userptr_t) stackptr /*userspace addr of argv*/,
                      (userptr_t) stackptr /*userspace addr of environment*/, stackptr, entrypoint);

    /* enter_new_process does not return. */
    panic("enter_new_process returned\n");

    *err = EINVAL;
    return -1;
}
int sys_execv(userptr_t progname, userptr_t *arguments) {
    struct proc *proc = curproc;
    struct addrspace *as;
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    int result;

    //kprintf("****EXECV]***** process-%d trying to exec", proc->pid);

    //lock_acquire(execlock);
    //kprintf("****EXECV]***** process-%d acquired exec lock", proc->pid);
	if(progname == NULL || progname == (void *)0x80000000 || progname == (void *)0x40000000) {
		return EFAULT;
	}

    if(arguments == NULL || arguments == (void *)0x80000000 || arguments == (void *)0x40000000) {
        return EFAULT;
    }
    /* This process should have an address space copied during fork */
    KASSERT(proc != NULL);
    char *_progname;
    size_t size;
    int i=0, count=0;
    _progname = (char *) kmalloc(sizeof(char)*PATH_MAX);
    result = copyinstr(progname, _progname, PATH_MAX, &size);
    if(result) {
        kfree(_progname);
        return EFAULT;
    }
    if(strlen(_progname) == 0) {
        kfree(_progname);
        return EINVAL;
    }
	if(swapping_started == true) {
    }
    kfree(_progname);

    char *args = (char *) kmalloc(sizeof(char)*ARG_MAX);
    result = copyinstr((const_userptr_t)arguments, args, ARG_MAX, &size);
    if(result) {
        kfree(args);
        return EFAULT;
    }
    /* Copy the user arguments on to the kernel */
   
    int offset = 0;
    while((char *) arguments[count] != NULL) {
        result = copyinstr((const_userptr_t) arguments[count], args+offset, ARG_MAX, &size);
        if(result) {
            kfree(args);
            return EFAULT;
        }
        offset += size;
        count++;
    }

    /* Open the file */
    result = vfs_open((char *)progname, O_RDONLY, 0, &v);
    if(result) {
        kfree(args);
        return result;
    }

    /* Destroy the current address space and Create a new address space */
    as_destroy(proc->p_addrspace);
    proc->p_addrspace = NULL;
    
    KASSERT(proc_getas() == NULL);

    as = as_create();
    if(as == NULL) {
        kfree(args);
        vfs_close(v);
        return ENOMEM;
    }
    /* Switch to it and activate it */
    proc_setas(as);
    as_activate();

    /* Load the executable. */

  //  kprintf("free pages available before load_elf : %d \n", coremap_free_bytes()/4096);
    result = load_elf(v, &entrypoint);
    if(result) {
        kfree(args);
        vfs_close(v);
        return result;
    }

    /* Done with the file now */
    vfs_close(v);

    /* Define the user stack in the address space */
    result = as_define_stack(as, &stackptr);
    if(result) {
        kfree(args);
        return result;
    }

    i = 0;
    int prevlen = 0, cur = 0;
    char **stkargs=(char**) kmalloc(sizeof(char*)*(count+1));
    while(i < offset) {
        int len=0, olen;
        for(len=0; args[i] != '\0'; len++, i++);
        olen = len;
        len = len + (4 - len%4);

        char *arg = kmalloc(len);
        //arg = kstrdup(args+prevlen);

        //kprintf("%s\n", arg);
        int j = prevlen;
        for(int k=0; k<len; k++) {
            if(k >= olen)
                arg[k] = '\0';
            else
                arg[k] = args[j++];
        }

        //kprintf("%s\n", arg);
        stackptr -= len;
        result = copyout((const void *)arg, (userptr_t)stackptr, (size_t)len);
        if(result) {
            kfree(args);
            kfree(stkargs);
            return result;
        }
        kfree(arg);
        stkargs[cur++] = (char *)stackptr;
        prevlen += olen + 1;
        i++;
    }
    stkargs[cur] = NULL;
    kfree(args);

    for(i=(cur) ; i>=0; i--) {
        stackptr = stackptr - sizeof(char *);
        //kprintf("copying arg %d at [%p]\n", i, *(stkargs+i));
        result = copyout((const void *)(stkargs+i), (userptr_t) stackptr, (sizeof(char *)));
        if(result) {
            kfree(stkargs);
            return result;
        }
        prevlen += 4;
    }
    kfree(stkargs);
    
    //unsigned int free = coremap_free_bytes();
  //  unsigned int free_pages = free/4096;

  //  kprintf("free pages available : %d \n", free_pages);

    //lock_release(execlock);
    //kprintf("****EXECV]***** process-%d released exec lock", proc->pid);
    enter_new_process(count, (userptr_t) stackptr, NULL, stackptr, entrypoint);

    panic("enter_new_process returned\n");
    return EINVAL;
}
示例#12
0
文件: runprogram.c 项目: JayP16/OS161
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char **arguments, int argc)
{
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    int result;

    (void)arguments;

    /* Open the file. */
    result = vfs_open(progname, O_RDONLY, 0, &v);
    if (result) {
        return result;
    }

    /* We should be a new thread. */
    KASSERT(curthread->t_addrspace == NULL);

    /* Create a new address space. */
    curthread->t_addrspace = as_create();
    if (curthread->t_addrspace==NULL) {
        vfs_close(v);
        return ENOMEM;
    }

    /* Activate it. */
    as_activate(curthread->t_addrspace);


    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
        /* thread_exit destroys curthread->t_addrspace */
        vfs_close(v);
        return result;
    }

    /* Done with the file now. */
    vfs_close(v);

    /* Define the user stack in the address space */
    result = as_define_stack(curthread->t_addrspace, &stackptr);
    if (result) {
        /* thread_exit destroys curthread->t_addrspace */
        return result;
    }

    char **argv;
    char *arg;
    int length, padding;

    //For each argument: Add padding, Decrement stackptr and copyout args
    for (int i=0; i<argc; i++) {
        length = strlen(arguments[i])+1;
        padding = 4-(length % 4);
        //Add padding
        arg = add_padding(arguments[i], padding);
        length = length+padding;
        //Decrement stackptr
        stackptr -= length;
        argv[i] = (char *)stackptr;
        //Copyout
        copyout(arg, (userptr_t) stackptr, length);
    }
    //Null terminate argv
    stackptr -= sizeof(char *)*(argc+1);
    argv[argc] = NULL;
    //Copyout argv
    copyout(argv, (userptr_t) stackptr, sizeof(char *)*(argc+1));

    /* Warp to user mode. */
    enter_new_process(argc, (userptr_t) stackptr, stackptr-1, entrypoint);

    /* enter_new_process does not return. */
    panic("enter_new_process returned\n");
    return EINVAL;
}
示例#13
0
文件: runprogram.c 项目: mellwa/os
int
runprogram(char *progname, unsigned long argc, char **argv)
{	
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;
    
	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}
    
	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);
    
	/* Create a new address space. */
	#if OPT_A3
	as = as_create(progname);
	#else
	as = as_create();
	#endif
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

    
	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();
    

    
	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);
    
 
	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr); // find the stack pointer
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

    
    //add stuff
    stackptr = stackptr - (argc + 1)*sizeof(vaddr_t); //subtract number of arguments + 1 (space for pointers)
    
    unsigned long i;
    unsigned int len;
    unsigned int len2;
    char **buf = (char **)stackptr; // argv

    for(i=0; i<argc; i++){
        len = (strlen(argv[i])+1)*(sizeof(char)); // first str length + null char
        stackptr = stackptr - len; // adjust stack pointer for length of str

        buf[i] = (char*)stackptr; // assign pointer to argv[i]
        copyoutstr((void *)argv[i],(userptr_t)buf[i],len,&len2); // copy to userstack
    }
    unsigned int remainder = stackptr % 8;
	if(remainder != 0){
		stackptr = stackptr - remainder;
	}
    
    // pass arguments to user program
	/* Warp to user mode. */
	enter_new_process(argc, (userptr_t)buf /*userspace addr of argv*/,
                      stackptr, entrypoint);

	// stores into trap->a0 as argc
	// stores trap->a1 as argv
	// sets stack pointer
	
    
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
int
runprogram(char *progname)
{
    struct addrspace *as;
    struct vnode *v;
    vaddr_t entrypoint, stackptr;
    int result;

    /* Open the file. */
    result = vfs_open(progname, O_RDONLY, 0, &v);
    if (result) {
        return result;
    }

    /* We should be a new process. */
    KASSERT(proc_getas() == NULL);

    /* Create a new address space. */
    as = as_create();
    if (as == NULL) {
        vfs_close(v);
        return ENOMEM;
    }

    /* Switch to it and activate it. */
    proc_setas(as);
    as_activate();

    /* Load the executable. */
    result = load_elf(v, &entrypoint);
    if (result) {
        /* p_addrspace will go away when curproc is destroyed */
        vfs_close(v);
        return result;
    }

    /* Done with the file now. */
    vfs_close(v);

    /* Define the user stack in the address space */
    result = as_define_stack(as, &stackptr);
    if (result) {
        // p_addrspace will go away when curproc is destroyed
        return result;
    }

    struct vnode* v1;
    struct vnode* v2;
    struct vnode* v3;

    const char* name = "con:";


    char *con_name = kstrdup(name);
    char *con_name2 = kstrdup(name);
    char *con_name3 = kstrdup(name);



    /*char con_name[5];
    char con_name2[5];
    char con_name3[5];

    strcpy(con_name,name);
    strcpy(con_name2,name);
    strcpy(con_name3,name);
    */

    result = vfs_open(con_name, O_RDONLY, 0664, &v1);
    if(result)
    {
        return result;
    }

    result = vfs_open(con_name2, O_WRONLY, 0664, &v2);
    if(result)
    {
        return result;
    }
    result = vfs_open(con_name3, O_WRONLY, 0664, &v3);
    if(result)
    {
        return result;
    }
    kfree(con_name);
    kfree(con_name2);
    kfree(con_name3);
    struct file_handle* fh1 = file_handle_create();
    fh1->file = v1;
    fh1->openflags = O_RDONLY;
    fh1->ref_count  = 1;
    strcpy(fh1->file_name,"con:");
    curproc->t_file_table[0] = fh1;

    struct file_handle* fh2 = file_handle_create();
    fh2->file = v2;
    fh2->openflags = O_WRONLY;
    fh2->ref_count = 1;
    strcpy(fh2->file_name, "con:");
    curproc->t_file_table[1] = fh2;

    struct file_handle* fh3 = file_handle_create();
    fh3->file = v3;
    fh3->openflags = O_WRONLY;
    fh3->ref_count = 1;
    strcpy(fh3->file_name, "con:");
    curproc->t_file_table[2] = fh3;

    /* Warp to user mode. */
    //kprintf("[run program] releasing semaphore \n");
    enter_new_process(0 /*argc*/, 0 /*userspace addr of argv*/,
                      NULL /*userspace addr of environment*/,
                      stackptr, entrypoint);

    /* enter_new_process does not return. */
    panic("enter_new_process returned\n");
    return EINVAL;
}
示例#15
0
文件: runprogram.c 项目: Adam-Koza/A3
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, unsigned long nargs, char **args)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	// userptr_t addrOfArg = (userptr_t)stackptr; //mOVED
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	//Will store my pointers of arguments here, put in stack later.
	vaddr_t ptrToArgAddressInStack[nargs];
	
	// Had issues with data being stored at start of the stack.
	// Moving down to avoid writing/reading issue.
	stackptr = stackptr - 4;

	// Insert strings (my arguments), and store the address (in stack)
	// which we get from stack pointer into my array I defined earlier.
	unsigned long i;
	for (i = 0; i <	nargs; i++){
		result = insertArgToStack(&stackptr, args[i]);
		if (result){
			return result;
		}
		ptrToArgAddressInStack[i] = stackptr;
	}

	//Add a Null 4 byte buffer
	int fourBlank = (int)NULL;
	stackptr = stackptr - 4;
	result = copyout(&fourBlank, (userptr_t)stackptr, 4);

	if (result){
		return result;
	}

	// Insert the address values into the stack
	for (i = nargs; i > 0 ; i--){
		stackptr = stackptr - 4; 
		copyout(&ptrToArgAddressInStack[(i - 1)], (userptr_t)stackptr, 4);

	}
	userptr_t addrOfArg = (userptr_t) (stackptr);

	/* Warp to user mode. */
	enter_new_process(nargs /*argc*/, addrOfArg /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#16
0
int sys_execv(userptr_t progname, userptr_t uargs_ptr){

//	char* name

	int err;

	char* program = (char*)kmalloc(20);
	size_t prog_len;
	err = copyinstr((userptr_t)progname, program, 1024, &prog_len);
	if(err){
		return err;
	}
	if(prog_len == 1) return EINVAL;

	char** uargs = (char**)kmalloc(100);       // this could be causing problems maybe
	err = copyin((userptr_t)uargs_ptr, uargs, 100);
	if(err){
		return err;
	}

	// Get number of arguments
	size_t nargs = 0;
	while(uargs[nargs] != NULL){
		nargs++;
		if(nargs >= MAX_ARGS){
			return E2BIG;
		}
	}
	int wordlen;
	int argLengths[nargs];		// Store the length of each argument, including the 1 null terminator
								// but NOT including the padding for alignment.
	for(size_t i = 0; i < nargs; i++){
		char arg[100];
		err = copyin((userptr_t)uargs[i],arg,100);
		if(err) return err;
		wordlen = strlen(uargs[i]) + 1; // Add 1 to account for Null terminator!
		//			pad = 4 - (wordlen % 4);		// Don't worry about padding yet
		//			if(pad == 4){ pad = 0; }		//
		//			totalLength += wordlen; 		// Don't need this...
		argLengths[i] = wordlen;
	}

	char** args = kmalloc(sizeof(char*) * nargs);	// Still need to populate args with each individual argument
	if(args == NULL){
		panic("kmalloc failed :'(");
	}

	size_t arg_num = 0;
	while(arg_num < nargs){
		args[arg_num] = kmalloc(argLengths[arg_num] * sizeof(char));
		err = copyin((userptr_t)uargs[arg_num], args[arg_num], argLengths[arg_num]);
		if(err) return err;
		arg_num++;
	}


	int result;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;

	/* Open the file. */
	result = vfs_open(program, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
//	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	// This is where runprogram stuff starts!

//	vaddr_t entrypoint, stackptr;
	int individualArgSize[nargs];

	size_t totalLength = 0;
	size_t pad;
	for(size_t i = 0; i < nargs; i++){
		wordlen = strlen(args[i]) + 1; // Add 1 to account for Null terminator!
		pad = 4 - (wordlen % 4);
		if(pad == 4){ pad = 0; }
		totalLength += wordlen + pad;
	}

	char* words_contiguous = kmalloc(sizeof(char) * totalLength);

	int j;
	for(size_t i = 0; i < nargs; i++){
		j = 0;
		while(args[i][j] != '\0'){
			*words_contiguous = args[i][j];
			words_contiguous++;
			j++;
		}
		// At this point, j is the length of the word without any null bytes.
		*words_contiguous = '\0';
		words_contiguous++;

		// Now calculate the number of padding null bytes for alignment.
		pad = 4 - ((j + 1) % 4);
		if(pad == 4){ pad = 0; }

		// Add the null bytes
		for(size_t p = 0; p < pad; p++){
			*words_contiguous = '\0';
			words_contiguous++;
		}
		individualArgSize[i] = j + 1 + pad; //Just getting the pointer size...
	}

	// Reset pointer back to start of C-string.
	words_contiguous = words_contiguous - totalLength;

	size_t totalStackSize;
	totalStackSize = totalLength + ((nargs + 1) * sizeof(char*));

	// Adjust to copyout the words (totalLength)
	stackptr = stackptr - totalLength;

	copyout(words_contiguous, (userptr_t)stackptr, totalLength);

	//	 Adjust to bottom of where we'll modify stack.
	//	stackptr = stackptr - (totalStackSize - totalLength);

	//	KASSERT((totalStackSize - totalLength) == sizeof(args));

	args[0] = (char*)stackptr;
	stackptr = stackptr + individualArgSize[0];
	for(size_t argNumber = 1; argNumber < nargs; argNumber++){
		args[argNumber] = (char*)stackptr;
		stackptr = stackptr + individualArgSize[argNumber];
	}
	// stackptr should be at 80000000 right now.

	// Set stackptr back to bottom of stack;
	stackptr = stackptr - totalStackSize;

	// Copy args (pointers to stack addresses) onto the stack, below the words.
	copyout(args, (userptr_t)stackptr, (totalStackSize - totalLength));

	// Create Null pointer.
	args[0] = NULL;

	// Copy null pointer to stack
	copyout(args, (userptr_t)(stackptr+((totalStackSize - totalLength) - 4)), 4);

	//	TODO: Free words contiguous at some point (memory leak)
	kfree(words_contiguous);
	kfree(args);
	kfree(program);
	//kfree(uargs);

	/* Warp to user mode. */ //TODO: Change
	enter_new_process(nargs /*argc*/, (userptr_t)stackptr /*userspace addr of argv*/,
			stackptr, entrypoint);

	(void)nargs;
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#17
0
int sys_execv(const char *prog, char **userArgs) {
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int res = 0;
	int length = 0;
	int index = 0;

	lock_acquire(allProcLock);
	char *progname;
	size_t size;
	progname = (char *) kmalloc(sizeof(char) * PATH_MAX);
	res = copyinstr((const_userptr_t) prog, progname, PATH_MAX, &size);
	char **args = (char **) kmalloc(sizeof(char **));
	res = copyin((const_userptr_t)userArgs, args, sizeof(char **));

	while (userArgs[index] != NULL) {
		args[index] = (char *) kmalloc(sizeof(char) * PATH_MAX);
		res = copyinstr((const_userptr_t) userArgs[index], args[index], PATH_MAX, &size);
		index++;
	}
	args[index] = NULL;
	index = 0;

	res = vfs_open(progname, O_RDONLY, 0, &v);

	struct addrspace *temp;
	temp = curproc->p_addrspace;

	if(curproc->p_addrspace != NULL){
		as_destroy(curproc->p_addrspace);
		curproc->p_addrspace = NULL;
	}

	KASSERT(curproc->p_addrspace == NULL);

	if((curproc->p_addrspace = as_create()) == NULL){
		kfree(progname);
		kfree(args);
		vfs_close(v);
		return ENOMEM;
	}

	as_activate();

	res = load_elf(v, &entrypoint);
	vfs_close(v);

	res = as_define_stack(curproc->p_addrspace, &stackptr);

	while(args[index] != NULL) {
		char * arg;
		length = strlen(args[index]) + 1;
		int orignalLength = length;
		if(length % 4 != 0) {
			length = length + (4 - length % 4);
		}
		arg = kmalloc(sizeof(length));
		arg = kstrdup(args[index]);

		for(int i = 0; i < length; i++){
			if(i >= orignalLength){
				arg[i] = '\0';
			}
			else{
				arg[i] = args[index][i];
			}
		}
		stackptr -= length;
		res = copyout((const void *) arg, (userptr_t) stackptr, (size_t) length);
		kfree(arg);
		args[index] = (char *) stackptr;
		index++;
	}
	if(args[index] == NULL){
		stackptr -= 4 * sizeof(char);
	}

	for(int i = (index - 1); i >= 0; i--) {
		stackptr = stackptr - sizeof(char*);
		res = copyout((const void *) (args + i), (userptr_t) stackptr, sizeof(char*));
	}
	kfree(progname);
	kfree(args);
	lock_release(allProcLock);
	enter_new_process(index, (userptr_t) stackptr, stackptr, entrypoint);
	return EINVAL;

}
示例#18
0
runprogram(char *progname)
#endif
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	//kprintf("bla0\n");
	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}
	//kprintf("bla1\n");
	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);
	//kprintf("bla2\n");
	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}
	//kprintf("bla3\n");
	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();
	//kprintf("bla4\n");
	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}
	//kprintf("bla5\n");
	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

#if OPT_A2
	//kprintf("bla6\n");
	if(args == NULL){
		return EFAULT;
	}	
	// copy args to user
	size_t len = sizeof(char *) * (num + 1);
	char **copyargs = kmalloc(len);
 	for(unsigned long int i = 0; i < num; i++){
    	len = strlen(args[i]) + 1;
    	stackptr = stackptr - ROUNDUP(len, 8);//? limit or valid stackptr //new

    	result = copyoutstr(args[i], (userptr_t)stackptr, len, NULL);//new
    	if(result){
    		kfree(copyargs);
      		return result;
    	}

    	copyargs[i] = (char *)stackptr;
  	}
  	copyargs[num] = NULL;

  	// copy arr
  	len = sizeof(char *) * (num + 1);
 	stackptr = stackptr - ROUNDUP(len, 8);
  	result = copyout(copyargs, (userptr_t)stackptr, len);
  	kfree(copyargs);
  	if(result){
    	return result;
  	}

  	userptr_t stackk = (userptr_t)stackptr;

  	enter_new_process(num /*argc*/, stackk /*userspace addr of argv*/,
			  stackptr, entrypoint);
#else
	/* Warp to user mode. */
	enter_new_process(0 /*argc*/, NULL /*userspace addr of argv*/,
			  stackptr, entrypoint);
#endif
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#19
0
int
execv(const char *prog_name, char **argv)
{
	if(	   prog_name == NULL || argv == NULL  ) return EFAULT;

	int argc = 0;
	size_t actual;
	char progname[__NAME_MAX];
	int err = copyinstr((const_userptr_t) prog_name, progname, __NAME_MAX, &actual);
	if(err != 0){
		return EFAULT;
	}

	/*if (	progname == (const char *)0x40000000 || progname == (const char *)0x80000000 ||
			argv == (char **)0x40000000 || argv == (char **)0x80000000)		return EFAULT;
	if(    strcmp(progname,"")    ) return EFAULT;
	if(    strcmp((const char*)*argv,"")    ) return EINVAL;
	if(    strcmp(progname,"\0")   ) return EINVAL;
	if(    strcmp((const char*)*argv,"\0")   ) return EINVAL;
	if(    strlen(progname) == 0   ) return EINVAL;
	if(    strlen((const char*)*argv) == 0   ) return EINVAL;*/

	int i;
	for(i=0 ; argv[i] != NULL ; i++){
		if(argv == (char **)0x40000000 || argv == (char **)0x80000000)
			return EFAULT;
	}
	argc = i;

	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	//Copy arguments into Temporary Kernel buffer
	char *ktemp[argc];
	int argvlen[argc];

	for( int m=0; m <argc; m++)
	{
		int len = strlen(argv[m])+1;
		argvlen[m] = len;
		int len_padding = len + (4 - (len % 4));
		ktemp[m] = kmalloc(len_padding);
		size_t *p;
		err = copyinstr((const_userptr_t)argv[m], ktemp[m], len, p);
	}

	/* Open the file. */
	result = vfs_open((char*)progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	//KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	// Load the arguments in user stack
	vaddr_t kargv[argc];
	size_t len_from_top = 0;
	int arglen = 0, arglen_pad=0;


	if(argc > 0)
	{
		//kargv[argc]=0;
		for(int i=0 ; i < argc ; i++){
			arglen = argvlen[i];
			arglen_pad =arglen	+ (4- ((arglen)%4));
			len_from_top = len_from_top + arglen_pad ;
			kargv[i] =  stackptr - len_from_top;
			copyout(ktemp[i], (userptr_t) kargv[i], arglen_pad);
			kfree((void*)ktemp[i]);
		}
		stackptr = stackptr - len_from_top -(argc)*sizeof(vaddr_t);
		for(int i=0 ; i <argc ; i++){
			copyout( &kargv[i], (userptr_t) stackptr, sizeof(vaddr_t));
			stackptr = stackptr + sizeof(vaddr_t);
		}

		stackptr = stackptr - (argc)*sizeof(vaddr_t);

		/* Warp to user mode. */
		enter_new_process( argc /*argc*/, (userptr_t) stackptr /*userspace addr of argv*/,
				stackptr, entrypoint);
	}
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#20
0
void
run_process(void *ptr, unsigned long num)
{
    (void)num;
    int result;
	vaddr_t entrypoint, stackptr;
    
    // extract and free passed-in context
    struct new_process_context *ctxt = (struct new_process_context *)ptr;
    struct process *proc = ctxt->proc;
    struct vnode *v = ctxt->executable;
    int nargs = ctxt->nargs;
    char **args = ctxt->args;
    kfree(ctxt);
    
    // attach process to thread
    curthread->t_proc = proc;
    proc->ps_thread = curthread;
    
	// Activate address space
	as_activate(proc->ps_addrspace);
    
	// Load the executable
	result = load_elf(v, &entrypoint);
	if (result) {
		vfs_close(v);
        kprintf("runprogram failed: %s\n", strerror(result));
        // alert the kernel menu that the process aborted
        process_finish(proc, _MKWAIT_SIG(SIGABRT));
		return;
	}
    
	// Done with the file now
	vfs_close(v);
    
	// Define the user stack in the address space
	result = as_define_stack(proc->ps_addrspace, &stackptr);
	if (result) {
        kprintf("runprogram failed: %s\n", strerror(result));
        // alert the kernel menu that the process aborted
        process_finish(proc, _MKWAIT_SIG(SIGABRT));
		return;
	}
	
	// Copy out arguments
	userptr_t uargv[nargs + 1];
    for (int i = 0; i < nargs; i++)
    {
        int aligned_length = WORD_ALIGN(strlen(args[i]) + 1);
        stackptr -= aligned_length;
        uargv[i] = (userptr_t)stackptr;
        size_t arg_len;
        result = copyoutstr(args[i], uargv[i], strlen(args[i]) + 1, &arg_len);
        if (result) {
            kprintf("runprogram failed: %s\n", strerror(result));
            // alert the kernel menu that the process aborted
            process_finish(proc, _MKWAIT_SIG(SIGABRT));
            return;
        }
    }
    uargv[nargs] =(userptr_t)NULL;
    
    // Copy out the argv array itself
	stackptr -= (nargs + 1) * sizeof(userptr_t);
	result = copyout(uargv, (userptr_t)stackptr,
                     (nargs + 1) * sizeof(userptr_t));
	if (result) {
        kprintf("runprogram failed: %s\n", strerror(result));
        // alert the kernel menu that the process aborted
        process_finish(proc, _MKWAIT_SIG(SIGABRT));
	    return;
	}
    
    enter_new_process(nargs, (userptr_t)stackptr, stackptr, entrypoint);
    
    // enter_new_process() does not return
	panic("enter_new_process returned\n");
}
示例#21
0
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname)
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

  /** Initialize the file descriptors for console**/
	if (curthread->t_fdtable[0] == NULL) {
			result = init_file_descriptor();
			if (result ) { // file descriptors not initialized
				 kprintf_n("init_file_descriptor failed");
				 return result;
			}
	}
	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new process. */
	KASSERT(proc_getas() == NULL);

	/* Create a new address space. */
	as = as_create();
	if (as == NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Switch to it and activate it. */
	proc_setas(as);
	as_activate();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

	/* Warp to user mode. */
	enter_new_process(0 /*argc*/, NULL /*userspace addr of argv*/,
			  NULL /*userspace addr of environment*/,
			  stackptr, entrypoint);

	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#22
0
int
sys_execv(const_userptr_t path, const_userptr_t argv)
{
    int err;
    struct process *proc = curthread->t_proc;
    
    char *kpath = kmalloc(PATH_MAX);
    if (kpath == NULL)
        return ENOMEM;
    
    // copy in path
    size_t path_len;
    if ((err = copyinstr(path, kpath, PATH_MAX, &path_len)))
    {
        kfree(kpath);
        return err;
    }
    
    // give the process a new name
    char *old_name = proc->ps_name;
    proc->ps_name = kstrdup(kpath);
    if (proc->ps_name == NULL)
    {
        proc->ps_name = old_name;
        kfree(kpath);
        return ENOMEM;
    }
    
    // copy in args
    size_t argc;
    size_t total_len;
    char **kargv = kmalloc((ARGNUM_MAX + 1) * sizeof(char *));
    err = copyinargs(argv, kargv, &argc, &total_len);
    if (err)
    {
        kfree(proc->ps_name);
        proc->ps_name = old_name;
        kfree(kpath);
        return err;
    }
    
    // Open the file.
    struct vnode *v;
	err = vfs_open(kpath, O_RDONLY, 0, &v);
    kfree(kpath);
	if (err)
    {
        free_kargv(kargv);
        kfree(proc->ps_name);
        proc->ps_name = old_name;
		return err;
    }
    
    // set up new address space
    struct addrspace *old_as = curthread->t_proc->ps_addrspace;
    struct addrspace *as = as_create();
    if (as == NULL)
    {
        vfs_close(v);
        free_kargv(kargv);
        kfree(proc->ps_name);
        proc->ps_name = old_name;
        return ENOMEM;
    }
    proc->ps_addrspace = as;
    
    // Activate the new address space
    as_activate(as);
    
    vaddr_t entrypoint;
    err = load_elf(v, &entrypoint);
    if (err)
    {
        proc->ps_addrspace = old_as;
        as_activate(old_as);
        as_destroy(as);
        vfs_close(v);
        free_kargv(kargv);
        kfree(proc->ps_name);
        proc->ps_name = old_name;
        return err;
    }
    
    // close the file now, since we will not be returning
    // here from user mode.
    vfs_close(v);
    
    // set up user stack
    vaddr_t stackptr;
    err = as_define_stack(as, &stackptr);
    if (err)
    {
        proc->ps_addrspace = old_as;
        as_activate(old_as);
        as_destroy(as);
        free_kargv(kargv);
        kfree(proc->ps_name);
        proc->ps_name = old_name;
        return err;
    }
    
    // copy arguments at base of stack
    stackptr -= total_len;
    stackptr -= (argc + 1) * sizeof(userptr_t);
    err = copyoutargs((userptr_t)stackptr, kargv, argc, total_len);
    if (err)
    {
        proc->ps_addrspace = old_as;
        as_activate(old_as);
        as_destroy(as);
        free_kargv(kargv);
        kfree(proc->ps_name);
        proc->ps_name = old_name;
        return err;
    }
    
    // destroy old address space and free memory
    // that we will no longer need
    as_destroy(old_as);
    kfree(old_name);
    
    
    // Warp to user mode
    enter_new_process(argc, (userptr_t)stackptr, stackptr, entrypoint);
    
    // enter_new_process() does not return
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#23
0
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char **argv, int argc)
{
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	int i, bytes;
	vaddr_t argvaddr[argc+1];

	for (i = 0; i < argc; i++)
	{
		bytes = strlen(argv[i]);
		bytes += 4 - bytes%4; //padding
		stackptr -= bytes;
		argvaddr[i] = stackptr;
		copyout(argv[i], (userptr_t)stackptr, bytes);
		kfree(argv[i]);
	}
	kfree(argv);
	argvaddr[argc] = 0;
	stackptr -= sizeof(vaddr_t)*(argc+1);

	copyout(argvaddr, (userptr_t) stackptr, 4*(argc+1));



	/* Warp to user mode. */
	enter_new_process(argc /*argc*/,(userptr_t) stackptr /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#24
0
int sys_execv(userptr_t progname_ptr, userptr_t args_ptr){

	
	char* prog_name = kmalloc(PATH_MAX); 
	size_t prog_name_len;
	if((char*)progname_ptr == NULL || (char**)args_ptr == NULL){
		return EFAULT;
	}
	int argc = 0;
	char** args_ptrs = kmalloc(ARG_MAX);
        while(1){
                char* arg = NULL;
                copyin(args_ptr+argc*sizeof(char*), &arg, sizeof(char*));
		args_ptrs[argc] = arg;
		if(arg != NULL){
			argc++;
		}else{
			break;
		}
	}
	if(argc> 64){
		return E2BIG;
	}

	int result_prog_name = copyinstr(progname_ptr,prog_name,PATH_MAX, &prog_name_len);
	if(result_prog_name != 0){
		return result_prog_name;
	}


	char* argv = kmalloc(ARG_MAX);
	size_t * arg_offsets = kmalloc(argc * sizeof(size_t));
        int offset = 0;
	for(int i = 0; i < argc; i++){
		//char* arg = kmalloc(ARG_MAX);
		size_t arg_len;
		int result = copyinstr((userptr_t)args_ptrs[i],
				 argv+offset, ARG_MAX - offset, &arg_len );
		if(result != 0){
			return result;
		}
		arg_offsets[i] = offset;
		offset += ROUNDUP(arg_len+1,8);
		//argv[i] = arg;
	}

	// prog_name (char*)   AND   argv (char*)

	struct addrspace *curproc_as = curproc_getas();
	

	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	vaddr_t cur_ptr;
	int result;
	/* Open the file. */
	result = vfs_open(prog_name, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}
	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();
	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}
	/* Done with the file now. */
	vfs_close(v);
	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);

	// Have both argc and prog_name ready for runprogram
	cur_ptr = stackptr;
	cur_ptr -= offset;
	result = copyout(argv, (userptr_t)cur_ptr, offset);
	if(result != 0){
		return result;
	}

	userptr_t * arg_offsets_up = kmalloc(sizeof(userptr_t) * (argc+1));
	for(int i = 0; i < argc; i++){
		userptr_t ptr = (userptr_t)cur_ptr +  arg_offsets[i];
		arg_offsets_up[i] = ptr;
	}
	arg_offsets_up[argc] = NULL;

	cur_ptr -= sizeof(userptr_t) * (argc+1);

	result = copyout(arg_offsets_up, (userptr_t)cur_ptr, sizeof(userptr_t) * (argc+1) );

	if(result != 0){
		return result;
	}

	as_destroy(curproc_as);
	kfree(arg_offsets);
	kfree(arg_offsets_up);
	kfree(argv);
	kfree(args_ptrs);
	kfree(prog_name);

	enter_new_process(argc /*argc*/, (userptr_t)cur_ptr /*userspace addr of argv*/,
	cur_ptr, entrypoint);
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;

	//return 0;
}
示例#25
0
文件: psyscall.c 项目: coderpm/OS161
int
sys___execv(char * p_name,char **ar )
{
	struct vnode *p_vnode;
		vaddr_t  stackptr;
		vaddr_t entrypoint;

		int result;
		size_t copied_length;
		char *kname;

		if(p_name==NULL)
			return EFAULT;

		if(ar==NULL)
			return EFAULT;

		if(p_name == '\0')
			return ENOEXEC;


		kname = (char *) kmalloc(sizeof(p_name));
		result = copyinstr((const_userptr_t)p_name,kname,NAME_MAX,&copied_length);
		if(copied_length == 1)
		{
			kfree(kname);
			return EINVAL;
		}
		if(result)
		{
			kfree(kname);
			return result;
		}

		char **karguments1 = kmalloc(100*sizeof(char*));
		result = copyin((const_userptr_t) ar,karguments1,(100*sizeof(char*)));
		if(result)
		{
			kfree(karguments1);
			kfree(kname);
			return result;
		}
		else
			kfree(karguments1);

		char **arguments_kernel =(char **) kmalloc(sizeof(char**));
		result = copyin((const_userptr_t) ar,arguments_kernel,(sizeof(char**)));
		if(result)
		{
			kfree(kname);
			kfree(arguments_kernel);
			return result;

		}

		char **karguments = (char **) kmalloc(sizeof(char **));

		int counter=0;
		size_t actual_lenght1;
		while(!(ar[counter]==NULL))
		{
			int string_length = strlen(ar[counter])+1;
			karguments[counter] = (char *) kmalloc(sizeof(char) * string_length);
			result = copyinstr((const_userptr_t) ar[counter],karguments[counter],string_length,&actual_lenght1);
			if(result)
			{
				kfree(kname);
				kfree(arguments_kernel);
				return result;
			}

			counter++;
		}
		karguments[counter] = NULL;

		result = vfs_open(kname, O_RDONLY, 0, &p_vnode);
		if (result) {
			return result;
		}

		as_destroy(curthread->t_addrspace);

		//Create a new address space.
		curthread->t_addrspace = as_create();
		if (curthread->t_addrspace==NULL)
		{
			vfs_close(p_vnode);
			return ENOMEM;
		}

		//Activate it.
		as_activate(curthread->t_addrspace);

		/* Load the executable. */
		result = load_elf(p_vnode, &entrypoint);
		if (result)
		{
			/* thread_exit destroys curthread->t_addrspace */
			vfs_close(p_vnode);
			return result;
		}

		/* Done with the file now. */
		vfs_close(p_vnode);

		//Get the pointer to the stack starting
		result = as_define_stack(curthread->t_addrspace, &stackptr);
		if (result)
		{
			/* thread_exit destroys curthread->t_addrspace */
			return result;
		}

		//Now copy the arguments
		int count =0;
		char **karray= kmalloc(sizeof(char**));
		size_t final_stack=0;

		while(karguments[count] != NULL)
		{
			int string_length = strlen(karguments[count])+1;
			char *k_des= karguments[count];

			int new_length = string_length;
			if((string_length) % 4 != 0)
			{
				while(new_length%4 !=0)
				{
					new_length++;
				}
				for(int i=string_length;i<=new_length;i++)
				{
					k_des[i]= '\0';
				}
			}

			//Argument aligned by 4

			size_t final_length= (size_t)new_length;

			if(count==0)
			{
				final_stack= stackptr- final_length;
			}
			else
			{
				final_stack= (size_t)karray[count-1]- final_length;
			}

			size_t actual_length1;
			result= copyoutstr(k_des, (userptr_t) (final_stack), final_length, &actual_length1);
			if(result)
			{
				return result;
			}

			karray[count]=  (char*)(final_stack);

			count++;
		} //End of While

		karray[count]= (char*)NULL;
		int value= count+1;
		int arr_length = (value+1)*sizeof(char*);
		final_stack= (size_t)karray[count-1]- arr_length;
		result= copyout(karray, (userptr_t) (final_stack),arr_length);
		if(result)
		{
			return result;
		}


			/* Warp to user mode. */
				enter_new_process(count /*argc*/, (userptr_t)(final_stack) /*userspace addr of argv*/,
						final_stack, entrypoint);

		return 0;
}
示例#26
0
runprogram(char *progname)
#endif
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);

	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Switch to it and activate it. */
  curproc_setas(as);
  as_activate();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

#if OPT_A2
  // How much space do we need for args in stack?
  // We need space for each pointer (4argc)
  // We need space for each character, including NULL termination, plus
  // padding to make multiples of 4
  int stringSpace = 0;
  for (unsigned long i = 0; i < argc; i++) {
    stringSpace += strlen(argv[i]) + 1;
  }

  // Align stack pointer to an 8-byte alignment
  while ((stackptr - (4*argc) - stringSpace) % 8 != 0) {
    stackptr--;
  }

  // Use a vaddr array to track the addresses the strings end up in
  // One bigger than argc to also have the pointer to the final NULL
  // value
  vaddr_t stringAddr[argc+1];

  // Copy argument strings onto stack
  // Array must end with NULL pointer, so do that first
  stackptr -= 4;
  copyout((void *)NULL, (userptr_t)stackptr, (size_t)4);
  stringAddr[argc] = stackptr;
  for (int i = argc-1; i >= 0; i--) {
    stackptr -= strlen(argv[i]) + 1;
    while (stackptr % 4 != 0) stackptr--;
    copyoutstr(argv[i], (userptr_t)stackptr, (size_t)strlen(argv[i]), NULL);
    stringAddr[i] = stackptr;
  }

  // Now use the stored addresses of the string to add the appropriate
  // pointers to the stack
  for (int i = argc; i >= 0; i--) {
    stackptr -= sizeof(vaddr_t);
    copyout(&stringAddr[i], (userptr_t)stackptr, sizeof(vaddr_t));
  }

	/* Warp to user mode. */
	enter_new_process(argc /*argc*/, (userptr_t)stackptr /*userspace addr of argv*/,
			  stackptr, entrypoint);
#else
	/* Warp to user mode. */
	enter_new_process(0 /*argc*/, NULL /*userspace addr of argv*/,
			  stackptr, entrypoint);
#endif

	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#27
0
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int
runprogram(char *progname, char** args, size_t nargs)
{
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;
	int argc = 0;

	while(args[argc] != NULL) {
	    argc++;
	}



	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new process. */
	KASSERT(curproc_getas() == NULL);

	/* Create a new address space. */
	as = as_create();
	if (as ==NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Switch to it and activate it. */
	curproc_setas(as);
	as_activate();

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(as, &stackptr);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}

	#if OPT_A2

	while(stackptr %8 != 0)
		stackptr--;

	vaddr_t argptr[argc + 1];
	for (int i = argc - 1; i >= 0; i--)
	{
		stackptr -= strlen(args[i]) + 1;
		result = copyoutstr(args[i], (userptr_t) stackptr, strlen(args[i]) + 1, NULL);
		if(result)
			return result;
		argptr[i] = stackptr;
	}

	while(stackptr % 4 != 0)
		stackptr--;
	//int hack = (int) nargs;

	argptr[nargs] = 0;

	for (int i = argc; i >= 0; i--)
	{
		stackptr -= ROUNDUP(sizeof(vaddr_t), 4);
		result = copyout(&argptr[i], (userptr_t) stackptr, sizeof(vaddr_t));
		if(result)
			return result;
	}
	#endif
	/* Warp to user mode. */
	enter_new_process(nargs /*argc*/, (userptr_t) stackptr /*userspace addr of argv*/,
			  stackptr, entrypoint);
	
	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");
	return EINVAL;
}
示例#28
0
/*
 * Load program "progname" and start running it in usermode.
 * Does not return except on error.
 *
 * Calls vfs_open on progname and thus may destroy it.
 */
int runprogram(char *progname, char **args, unsigned long nargs) {
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;

	/*Initialize Console*/

	char *consolein;
	char *consoleout;
	char *consoleerr;

	consolein = kstrdup("con:");
	consoleout = kstrdup("con:");
	consoleerr = kstrdup("con:");

	curthread->t_fdtable[0] = (struct fdesc*) kmalloc(sizeof(struct fdesc));

	if (vfs_open(consolein, O_RDONLY, 0664, &(curthread->t_fdtable[0]->vn))) {
		return EINVAL;
	}

	curthread->t_fdtable[0]->name = consolein;
	curthread->t_fdtable[0]->flag = O_RDONLY;
	curthread->t_fdtable[0]->ref_count = 1;
	curthread->t_fdtable[0]->filelock = lock_create("STDIN");

	kfree(consolein);

	curthread->t_fdtable[1] = (struct fdesc*) kmalloc(sizeof(struct fdesc));

	if (vfs_open(consoleout, O_WRONLY, 0664, &(curthread->t_fdtable[1]->vn))) {
		return EINVAL;
	}

	curthread->t_fdtable[1]->name = consoleout;
	curthread->t_fdtable[1]->flag = O_WRONLY;
	curthread->t_fdtable[1]->ref_count = 1;
	curthread->t_fdtable[1]->filelock = lock_create("STDOUT");

	kfree(consoleout);

	curthread->t_fdtable[2] = (struct fdesc*) kmalloc(sizeof(struct fdesc));

	if (vfs_open(consoleerr, O_WRONLY, 0664, &(curthread->t_fdtable[2]->vn))) {
		return EINVAL;
	}

	curthread->t_fdtable[2]->name = consoleerr;
	curthread->t_fdtable[2]->flag = O_WRONLY;
	curthread->t_fdtable[2]->ref_count = 1;
	curthread->t_fdtable[2]->filelock = lock_create("STDERR");

	kfree(consoleerr);

	/*Console Initialized*/

	/* Open the file. */
	result = vfs_open(progname, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}

	/* We should be a new thread. */
	KASSERT(curthread->t_addrspace == NULL);

	/* Create a new address space. */
	curthread->t_addrspace = as_create();
	if (curthread->t_addrspace == NULL ) {
		vfs_close(v);
		return ENOMEM;
	}

	/* Activate it. */
	as_activate(curthread->t_addrspace);

	/* Load the executable. */
	result = load_elf(v, &entrypoint);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		vfs_close(v);
		return result;
	}

	/* Done with the file now. */
	vfs_close(v);

	/* Define the user stack in the address space */
	result = as_define_stack(curthread->t_addrspace, &stackptr);
	if (result) {
		/* thread_exit destroys curthread->t_addrspace */
		return result;
	}

	int argc = (signed) nargs;
	int err;
	char** argv;

	//kmalloc argv with size of char* times nargs+1
	argv = kmalloc((nargs + 1) * sizeof(userptr_t));

	size_t len;

	for (int i = 0; i < argc; i++) {

		len = strlen(args[i]) + 1;

		len = (len + 4 - 1) & ~(size_t) (4 - 1);

		stackptr -= len;

		if ((err = copyout(args[i], (userptr_t) stackptr, len)) != 0) {

			kprintf("error copyout");
		}

		argv[i] = (char*) stackptr;

	}

	argv[nargs] = NULL;

	stackptr -= (nargs + 1) * sizeof(userptr_t);

	if ((err = copyout(argv, (userptr_t) stackptr, (nargs + 1) * sizeof(char*)))) {
		kprintf("error copying");
	}

	/* Warp to user mode. */
	enter_new_process(argc, (userptr_t) stackptr /*userspace addr of argv*/,
			stackptr, entrypoint);

	/* enter_new_process does not return. */
	panic("enter_new_process returned\n");

	return EINVAL;
}
示例#29
0
int sys_execv(userptr_t progname, userptr_t args) {
	struct addrspace *as;
	struct vnode *v;
	vaddr_t entrypoint, stackptr;
	int result;
	
	char * path = kmalloc(PATH_MAX);

	as = curproc_getas();

	if (as != NULL && !valid_address_check(as, (vaddr_t)args)) { // out of vaddr boundary for this proc
		errno = EFAULT;
		return -1;
	}
	if (as != NULL && !valid_address_check(as, (vaddr_t)progname)) { // out of vaddr boundary for this proc
		errno = EFAULT;
		return -1;
	}

	result = copyinstr(progname, path, PATH_MAX, NULL);
	if(result) {
		return result;
	}
	if(*path == '\0') {
		errno = EISDIR;
		return -1;
	}

	// Open the executable, create a new address space and load the elf into it

	result = vfs_open((char *)path, O_RDONLY, 0, &v);
	if (result) {
		return result;
	}
	// KASSERT(curproc_getas() == NULL);

	as = as_create();
	if (as == NULL) {
		vfs_close(v);
		return ENOMEM;
	}

	curproc_setas(as);
	as_activate();

	result = load_elf(v, &entrypoint);
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		vfs_close(v);
		return result;
	}
	vfs_close(v);

	result = as_define_stack(as, &stackptr); // stackptr set
	if (result) {
		/* p_addrspace will go away when curproc is destroyed */
		return result;
	}
	kfree(path);

	userptr_t karg, uargs, argbase;
	char * buffer, * bufend;
	buffer = kmalloc(sizeof(ARG_MAX));
	if(buffer == NULL) {
		errno = ENOMEM;
		return -1;
	}
	bufend = buffer;
	size_t resid, bufsize;
	size_t alen;
	size_t *offsets = kmalloc(NARG_MAX * sizeof(size_t));
	if(offsets == NULL) {
		errno = ENOMEM;
		return -1;
	}
	int size = 0;
	userptr_t arg;


	resid = bufsize = ARG_MAX;

	for(int i = 0 ; i < NARG_MAX ; i++) { // copyin from user.
		copyin(args, &karg, sizeof(userptr_t)); // copy the pointer.
		if(karg == NULL) break; // if NULL, break.
		copyinstr(karg, bufend, resid, &alen);
		offsets[i] = bufsize - resid;
		bufend += alen;
		resid -= alen;
		args += sizeof(userptr_t);
		size++;
	}

	size_t buflen = bufend - buffer; // length of buffer.
	vaddr_t stack = stackptr - buflen; // current stack position.
	stack -= (stack & (sizeof(void *) - 1)); // alignment
	argbase = (userptr_t)stack; // argbase.

	copyout(buffer, argbase, buflen); // copy the arguments into stack.

	stack -= (size + 1)*sizeof(userptr_t); // go to array pointer (bottom of stack).
	uargs = (userptr_t)stack; // got stack.

	for(int i = 0 ; i < size ; i++) { // copy the elements
		arg = argbase + offsets[i];
		copyout(&arg, uargs, sizeof(userptr_t));
		uargs += sizeof(userptr_t); // 4
	}
	arg = NULL;
	copyout(&arg, uargs, sizeof(userptr_t)); // copy the NULL pointer.



	kfree(buffer);
	kfree(offsets);

	enter_new_process(size /*argc*/, (userptr_t)stack /*userspace addr of argv*/,
			  stack, entrypoint);

	return 0;

}