Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/freebsd32/freebsd32_misc.c
Show First 20 Lines • Show All 331 Lines • ▼ Show 20 Lines | |||||
* the pointers. | * the pointers. | ||||
*/ | */ | ||||
int | int | ||||
freebsd32_exec_copyin_args(struct image_args *args, const char *fname, | freebsd32_exec_copyin_args(struct image_args *args, const char *fname, | ||||
enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) | enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) | ||||
{ | { | ||||
char *argp, *envp; | char *argp, *envp; | ||||
u_int32_t *p32, arg; | u_int32_t *p32, arg; | ||||
size_t length; | |||||
int error; | int error; | ||||
bzero(args, sizeof(*args)); | bzero(args, sizeof(*args)); | ||||
if (argv == NULL) | if (argv == NULL) | ||||
return (EFAULT); | return (EFAULT); | ||||
/* | /* | ||||
* Allocate demand-paged memory for the file name, argument, and | * Allocate demand-paged memory for the file name, argument, and | ||||
* environment strings. | * environment strings. | ||||
*/ | */ | ||||
error = exec_alloc_args(args); | error = exec_alloc_args(args); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* Copy the file name. | * Copy the file name. | ||||
*/ | */ | ||||
if (fname != NULL) { | error = exec_args_add_fname(args, fname, segflg); | ||||
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) | if (error != 0) | ||||
goto err_exit; | goto err_exit; | ||||
} else | |||||
length = 0; | |||||
args->begin_argv = args->buf + length; | |||||
args->endp = args->begin_argv; | |||||
args->stringspace = ARG_MAX; | |||||
/* | /* | ||||
* extract arguments first | * extract arguments first | ||||
*/ | */ | ||||
p32 = argv; | p32 = argv; | ||||
for (;;) { | for (;;) { | ||||
error = copyin(p32++, &arg, sizeof(arg)); | error = copyin(p32++, &arg, sizeof(arg)); | ||||
if (error) | if (error) | ||||
goto err_exit; | goto err_exit; | ||||
if (arg == 0) | if (arg == 0) | ||||
break; | break; | ||||
argp = PTRIN(arg); | argp = PTRIN(arg); | ||||
error = copyinstr(argp, args->endp, args->stringspace, &length); | error = exec_args_add_arg(args, argp, UIO_USERSPACE); | ||||
if (error) { | if (error != 0) | ||||
if (error == ENAMETOOLONG) | |||||
error = E2BIG; | |||||
goto err_exit; | goto err_exit; | ||||
} | } | ||||
args->stringspace -= length; | |||||
args->endp += length; | |||||
args->argc++; | |||||
} | |||||
args->begin_envv = args->endp; | |||||
/* | /* | ||||
* extract environment strings | * extract environment strings | ||||
*/ | */ | ||||
if (envv) { | if (envv) { | ||||
p32 = envv; | p32 = envv; | ||||
for (;;) { | for (;;) { | ||||
error = copyin(p32++, &arg, sizeof(arg)); | error = copyin(p32++, &arg, sizeof(arg)); | ||||
if (error) | if (error) | ||||
goto err_exit; | goto err_exit; | ||||
if (arg == 0) | if (arg == 0) | ||||
break; | break; | ||||
envp = PTRIN(arg); | envp = PTRIN(arg); | ||||
error = copyinstr(envp, args->endp, args->stringspace, | error = exec_args_add_env(args, envp, UIO_USERSPACE); | ||||
&length); | if (error != 0) | ||||
if (error) { | |||||
if (error == ENAMETOOLONG) | |||||
error = E2BIG; | |||||
goto err_exit; | goto err_exit; | ||||
} | |||||
args->stringspace -= length; | |||||
args->endp += length; | |||||
args->envc++; | |||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
err_exit: | err_exit: | ||||
exec_free_args(args); | exec_free_args(args); | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 3,072 Lines • Show Last 20 Lines |