FreeBSD/sys/kern/kern_exec.c
/*
 * Copy out argument and environment strings from the old process address
 * space into the temporary string buffer.
 */
Copy out argument and environment strings from the old process address
space into the temporary string buffer.
Copy out argument and environment strings from the old process address space into the temporary string buffer .
int
exec_copyin_args(struct image_args *args, char *fname,
    enum uio_seg segflg, char **argv, char **envv)
{
	u_long argp, envp;
	int error;
	size_t length;
	bzero(args, sizeof(*args));
	if (argv == NULL)
		return (EFAULT);
	error = exec_alloc_args(args);
	if (error != 0)
		return (error);
	if (fname != NULL) {
		args->fname = args->buf;
		error = (segflg == UIO_SYSSPACE) ?
		    copystr(fname, args->fname, PATH_MAX, &length) :
		    copyinstr(fname, args->fname, PATH_MAX, &length);
		if (error != 0)
			goto err_exit;
	} else
		length = 0;
	args->begin_argv = args->buf + length;
	args->endp = args->begin_argv;
	args->stringspace = ARG_MAX;
	for (;;) {
		error = fueword(argv++, &argp);
		if (error == -1) {
			error = EFAULT;
			goto err_exit;
		}
		if (argp == 0)
			break;
		error = copyinstr((void *)(uintptr_t)argp, args->endp,
		    args->stringspace, &length);
		if (error != 0) {
			if (error == ENAMETOOLONG) 
				error = E2BIG;
			goto err_exit;
		}
		args->stringspace -= length;
		args->endp += length;
		args->argc++;
	}
	args->begin_envv = args->endp;
	if (envv) {
		for (;;) {
			error = fueword(envv++, &envp);
			if (error == -1) {
				error = EFAULT;
				goto err_exit;
			}
			if (envp == 0)
				break;
			error = copyinstr((void *)(uintptr_t)envp,
			    args->endp, args->stringspace, &length);
			if (error != 0) {
				if (error == ENAMETOOLONG)
					error = E2BIG;
				goto err_exit;
			}
			args->stringspace -= length;
			args->endp += length;
			args->envc++;
		}
	}
	return (0);
err_exit:
	exec_free_args(args);
	return (error);
}
int exec_copyin_args ( struct image_args * args , char * fname , enum uio_seg segflg , char * * argv , char * * envv ) { u_long argp , envp ; int error ; size_t length ; bzero ( args , sizeof ( * args ) ) ; if ( argv == NULL ) return ( EFAULT ) ; error = exec_alloc_args ( args ) ; if ( error != 0 ) return ( error ) ; if ( fname != NULL ) { args -> fname = args -> buf ; error = ( segflg == UIO_SYSSPACE ) ? copystr ( fname , args -> fname , PATH_MAX , & length ) : copyinstr ( fname , args -> fname , PATH_MAX , & length ) ; if ( error != 0 ) goto err_exit ; } else length = 0 ; args -> begin_argv = args -> buf + length ; args -> endp = args -> begin_argv ; args -> stringspace = ARG_MAX ; for ( ; ; ) { error = fueword ( argv ++ , & argp ) ; if ( error == -1 ) { error = EFAULT ; goto err_exit ; } if ( argp == 0 ) break ; error = copyinstr ( ( void * ) ( uintptr_t ) argp , args -> endp , args -> stringspace , & length ) ; if ( error != 0 ) { if ( error == ENAMETOOLONG ) error = E2BIG ; goto err_exit ; } args -> stringspace -= length ; args -> endp += length ; args -> argc ++ ; } args -> begin_envv = args -> endp ; if ( envv ) { for ( ; ; ) { error = fueword ( envv ++ , & envp ) ; if ( error == -1 ) { error = EFAULT ; goto err_exit ; } if ( envp == 0 ) break ; error = copyinstr ( ( void * ) ( uintptr_t ) envp , args -> endp , args -> stringspace , & length ) ; if ( error != 0 ) { if ( error == ENAMETOOLONG ) error = E2BIG ; goto err_exit ; } args -> stringspace -= length ; args -> endp += length ; args -> envc ++ ; } } return ( 0 ) ; err_exit : exec_free_args ( args ) ; return ( error ) ; }
Copy out argument and environment strings from the old process address
 space into the temporary string buffer.
Copy out argument and environment strings from the old process address space into the temporary string buffer .
/*
	 * Allocate demand-paged memory for the file name, argument, and
	 * environment strings.
	 */ /*
	 * Copy the file name.
	 */ /*
	 * extract arguments first
	 */ /*
	 * extract environment strings
	 */