Index: emulation/ibcs2/coff/imgact_coff.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/ibcs2/coff/imgact_coff.c,v retrieving revision 1.7 diff -u -u -r1.7 imgact_coff.c --- emulation/ibcs2/coff/imgact_coff.c 23 Sep 2003 05:03:50 -0000 1.7 +++ emulation/ibcs2/coff/imgact_coff.c 11 Nov 2003 06:38:37 -0000 @@ -333,11 +333,6 @@ ((const char*)(imgp->image_header) + sizeof(struct filehdr) + sizeof(struct aouthdr)); - if ((error = exec_extract_strings(imgp)) != 0) { - DPRINTF(("%s(%d): return %d\n", __FILE__, __LINE__, error)); - return error; - } - exec_new_vmspace(imgp); vmspace = imgp->proc->p_vmspace; Index: emulation/linux/i386/imgact_linux.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/linux/i386/imgact_linux.c,v retrieving revision 1.4 diff -u -u -r1.4 imgact_linux.c --- emulation/linux/i386/imgact_linux.c 27 Aug 2003 06:30:03 -0000 1.4 +++ emulation/linux/i386/imgact_linux.c 10 Nov 2003 10:44:04 -0000 @@ -109,11 +109,6 @@ a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur) return (ENOMEM); - /* copy in arguments and/or environment from old process */ - error = exec_extract_strings(imgp); - if (error) - return (error); - /* * Destroy old process VM and create a new one (with a new stack) */ Index: emulation/linux/i386/linux_sysvec.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/linux/i386/linux_sysvec.c,v retrieving revision 1.10 diff -u -u -r1.10 linux_sysvec.c --- emulation/linux/i386/linux_sysvec.c 10 Nov 2003 06:12:11 -0000 1.10 +++ emulation/linux/i386/linux_sysvec.c 11 Nov 2003 03:13:23 -0000 @@ -197,13 +197,13 @@ register_t *argv, *envp; argv = *stack_base; - envp = *stack_base + (imgp->argc + 1); + envp = *stack_base + (imgp->args->argc + 1); (*stack_base)--; **stack_base = (intptr_t)(void *)envp; (*stack_base)--; **stack_base = (intptr_t)(void *)argv; (*stack_base)--; - **stack_base = imgp->argc; + **stack_base = imgp->args->argc; return 0; } @@ -213,7 +213,7 @@ Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; register_t *pos; - pos = *stack_base + (imgp->argc + imgp->envc + 2); + pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); if (args->trace) { AUXARGS_ENTRY(pos, AT_DEBUG, 1); @@ -238,7 +238,7 @@ imgp->auxargs = NULL; (*stack_base)--; - **stack_base = (long)imgp->argc; + **stack_base = (long)imgp->args->argc; return 0; } Index: emulation/svr4/imgact_svr4.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/svr4/imgact_svr4.c,v retrieving revision 1.5 diff -u -u -r1.5 imgact_svr4.c --- emulation/svr4/imgact_svr4.c 27 Aug 2003 06:07:10 -0000 1.5 +++ emulation/svr4/imgact_svr4.c 11 Nov 2003 06:38:57 -0000 @@ -109,11 +109,6 @@ a_out->a_data + bss_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur) return (ENOMEM); - /* copy in arguments and/or environment from old process */ - error = exec_extract_strings(imgp); - if (error) - return (error); - /* * Destroy old process VM and create a new one (with a new stack) */ Index: emulation/svr4/svr4_sysvec.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/svr4/svr4_sysvec.c,v retrieving revision 1.8 diff -u -u -r1.8 svr4_sysvec.c --- emulation/svr4/svr4_sysvec.c 23 Sep 2003 05:03:51 -0000 1.8 +++ emulation/svr4/svr4_sysvec.c 11 Nov 2003 06:36:01 -0000 @@ -203,7 +203,7 @@ Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; register_t *pos; - pos = *stack_base + (imgp->argc + imgp->envc + 2); + pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); if (args->trace) { AUXARGS_ENTRY(pos, AT_DEBUG, 1); @@ -228,7 +228,7 @@ imgp->auxargs = NULL; (*stack_base)--; - **stack_base = (int)imgp->argc; + **stack_base = (int)imgp->args->argc; return 0; } Index: kern/imgact_aout.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/imgact_aout.c,v retrieving revision 1.6 diff -u -u -r1.6 imgact_aout.c --- kern/imgact_aout.c 27 Aug 2003 01:43:07 -0000 1.6 +++ kern/imgact_aout.c 10 Nov 2003 00:21:39 -0000 @@ -165,11 +165,6 @@ imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur) return (ENOMEM); - /* copy in arguments and/or environment from old process */ - error = exec_extract_strings(imgp); - if (error) - return (error); - /* * Destroy old process VM and create a new one (with a new stack) */ Index: kern/imgact_elf.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/imgact_elf.c,v retrieving revision 1.14 diff -u -u -r1.14 imgact_elf.c --- kern/imgact_elf.c 10 Nov 2003 18:09:12 -0000 1.14 +++ kern/imgact_elf.c 11 Nov 2003 06:26:42 -0000 @@ -362,7 +362,6 @@ * Initialize part of the common data */ imgp->proc = p; - imgp->uap = NULL; imgp->attr = attr; imgp->firstpage = NULL; imgp->image_header = (char *)kmem_alloc_wait(exec_map, PAGE_SIZE); @@ -494,6 +493,8 @@ Elf_Brandinfo *brand_info; char *path; + error = 0; + /* * Do we have a valid ELF header ? */ @@ -516,9 +517,6 @@ * From this point on, we may have resources that need to be freed. */ - if ((error = exec_extract_strings(imgp)) != 0) - goto fail; - exec_new_vmspace(imgp); /* @@ -724,7 +722,7 @@ Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; register_t *pos; - pos = *stack_base + (imgp->argc + imgp->envc + 2); + pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); if (args->trace) { AUXARGS_ENTRY(pos, AT_DEBUG, 1); @@ -745,7 +743,7 @@ imgp->auxargs = NULL; (*stack_base)--; - suword(*stack_base, (long) imgp->argc); + suword(*stack_base, (long) imgp->args->argc); return 0; } Index: kern/imgact_gzip.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/imgact_gzip.c,v retrieving revision 1.3 diff -u -u -r1.3 imgact_gzip.c --- kern/imgact_gzip.c 26 Aug 2003 21:09:02 -0000 1.3 +++ kern/imgact_gzip.c 11 Nov 2003 06:38:03 -0000 @@ -219,12 +219,6 @@ /* Find out how far we should go */ gz->file_end = gz->file_offset + gz->a_out.a_text + gz->a_out.a_data; - /* copy in arguments and/or environment from old process */ - error = exec_extract_strings(gz->ip); - if (error) { - gz->where = __LINE__; - return (error); - } /* * Destroy old process VM and create a new one (with a new stack) */ Index: kern/imgact_shell.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/imgact_shell.c,v retrieving revision 1.2 diff -u -u -r1.2 imgact_shell.c --- kern/imgact_shell.c 17 Jun 2003 04:28:41 -0000 1.2 +++ kern/imgact_shell.c 11 Nov 2003 06:09:45 -0000 @@ -42,15 +42,14 @@ /* * Shell interpreter image activator. A interpreter name beginning - * at imgp->stringbase is the minimal successful exit requirement. + * at imgp->args->begin_argv is the minimal successful exit requirement. */ int -exec_shell_imgact(imgp) - struct image_params *imgp; +exec_shell_imgact(struct image_params *imgp) { const char *image_header = imgp->image_header; - const char *ihp, *line_endp; - char *interp; + const char *ihp; + int error, length, offset; /* a shell script? */ if (((const short *) image_header)[0] != SHELLMAGIC) @@ -66,64 +65,83 @@ imgp->interpreted = 1; /* - * Copy shell name and arguments from image_header into string - * buffer. + * We must determine how far to offset the contents of the buffer + * to make room for the interpreter + args and the full path of + * the interpreted file while overwriting the first argument + * currently in the buffer. */ - - /* - * Find end of line; return if the line > MAXSHELLCMDLEN long. - */ - for (ihp = &image_header[2]; *ihp != '\n' && *ihp != '#'; ++ihp) { - if (ihp >= &image_header[MAXSHELLCMDLEN]) - return(ENAMETOOLONG); - } - line_endp = ihp; - - /* reset for another pass */ ihp = &image_header[2]; + offset = 0; + while (ihp < &image_header[MAXSHELLCMDLEN]) { + /* Skip any whitespace */ + while ((*ihp == ' ') || (*ihp == '\t')) + ihp++; + + /* End of line? */ + if ((*ihp == '\n') || (*ihp == '#')) + break; + + /* Found a token */ + while ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') && + (*ihp != '#')) { + offset++; + ihp++; + } + /* Include terminating nulls in the offset */ + offset++; + } - /* Skip over leading spaces - until the interpreter name */ - while ((*ihp == ' ') || (*ihp == '\t')) ihp++; - - /* copy the interpreter name */ - interp = imgp->interpreter_name; - while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) - *interp++ = *ihp++; - *interp = '\0'; - - /* Disallow a null interpreter filename */ - if (*imgp->interpreter_name == '\0') - return(ENOEXEC); + /* If the script gives a null line as the interpreter, we bail */ + if (offset == 0) + return (ENOEXEC); + + /* Check that we aren't too big */ + if (offset > MAXSHELLCMDLEN) + return (ENAMETOOLONG); + + /* The file name is used to replace argv[0] */ + offset += strlen(imgp->args->fname) + 1; + offset -= strlen(imgp->args->begin_argv) + 1; + + if (offset > imgp->args->space) + return (E2BIG); + + /* Move the contents of imgp->args->buf by offset bytes. */ + bcopy(imgp->args->buf, imgp->args->buf + offset, + ARG_MAX - imgp->args->space); - /* reset for another pass */ + /* + * Loop through the interpreter name yet again, copying as + * we go. + */ ihp = &image_header[2]; + offset = 0; + while (ihp < &image_header[MAXSHELLCMDLEN]) { + /* Skip whitespace */ + while ((*ihp == ' ' || *ihp == '\t')) + ihp++; + + /* End of line? */ + if ((*ihp == '\n') || (*ihp == '#')) + break; + + /* Found a token, copy it */ + while ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') && + (*ihp != '#')) + imgp->args->buf[offset++] = *ihp++; - /* copy the interpreter name and arguments */ - while (ihp < line_endp) { - /* Skip over leading spaces */ - while ((*ihp == ' ') || (*ihp == '\t')) ihp++; - - if (ihp < line_endp) { - /* - * Copy to end of token. No need to watch stringspace - * because this is at the front of the string buffer - * and the maximum shell command length is tiny. - */ - while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) { - *imgp->stringp++ = *ihp++; - imgp->stringspace--; - } - - *imgp->stringp++ = 0; - imgp->stringspace--; - - imgp->argc++; - } + imgp->args->buf[offset++] = '\0'; + imgp->args->argc++; } - imgp->argv0 = imgp->uap->fname; + error = copystr(imgp->args->fname, imgp->args->buf + offset, + imgp->args->space, &length); + + if (error == 0) + error = copystr(imgp->args->begin_argv, + imgp->interpreter_name, MAXSHELLCMDLEN, &length); - return(0); + return (error); } /* Index: kern/kern_exec.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/kern_exec.c,v retrieving revision 1.13 diff -u -u -r1.13 kern_exec.c --- kern/kern_exec.c 5 Nov 2003 23:26:20 -0000 1.13 +++ kern/kern_exec.c 11 Nov 2003 05:06:22 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -83,27 +84,50 @@ int ps_argsopen = 1; SYSCTL_INT(_kern, OID_AUTO, ps_argsopen, CTLFLAG_RW, &ps_argsopen, 0, ""); +void print_execve_args(struct image_args *args); +int debug_execve_args = 0; +SYSCTL_INT(_kern, OID_AUTO, debug_execve_args, CTLFLAG_RW, &debug_execve_args, + 0, ""); + +void +print_execve_args(struct image_args *args) +{ + char *cp; + int ndx; + + cp = args->begin_argv; + for (ndx = 0; ndx < args->argc; ndx++) { + printf("\targv[%d]: %s\n", ndx, cp); + while (*cp++ != '\0'); + } + for (ndx = 0; ndx < args->envc; ndx++) { + printf("\tenvv[%d]: %s\n", ndx, cp); + while (*cp++ != '\0'); + } +} + /* * Each of the items is a pointer to a `const struct execsw', hence the * double pointer here. */ static const struct execsw **execsw; -/* - * execve() system call. - */ int -execve(struct execve_args *uap) +kern_execve(struct nameidata *ndp, struct image_args *args) { struct thread *td = curthread; struct proc *p = td->td_proc; - struct nameidata nd, *ndp; register_t *stack_base; int error, len, i; struct image_params image_params, *imgp; struct vattr attr; int (*img_first) (struct image_params *); + if (debug_execve_args) { + printf("%s()\n", __func__); + print_execve_args(args); + } + KKASSERT(p); imgp = &image_params; @@ -120,14 +144,11 @@ * Initialize part of the common data */ imgp->proc = p; - imgp->uap = uap; + imgp->args = args; imgp->attr = &attr; - imgp->argc = imgp->envc = 0; - imgp->argv0 = NULL; imgp->entry_addr = 0; imgp->vmspace_destroyed = 0; imgp->interpreted = 0; - imgp->interpreter_name[0] = '\0'; imgp->auxargs = NULL; imgp->vp = NULL; imgp->firstpage = NULL; @@ -137,34 +158,26 @@ * Allocate temporary demand zeroed space for argument and * environment strings */ - imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + PAGE_SIZE); - if (imgp->stringbase == NULL) { + imgp->image_header = (char *)kmem_alloc_wait(exec_map, PAGE_SIZE); + if (imgp->image_header == NULL) { error = ENOMEM; goto exec_fail; } - imgp->stringp = imgp->stringbase; - imgp->stringspace = ARG_MAX; - imgp->image_header = imgp->stringbase + ARG_MAX; + +interpret: /* * Translate the file name. namei() returns a vnode pointer * in ni_vp amoung other things. */ - ndp = &nd; - NDINIT(ndp, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_FOLLOW | CNP_SAVENAME, - UIO_USERSPACE, uap->fname, td); - -interpret: - error = namei(ndp); if (error) { - kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, - ARG_MAX + PAGE_SIZE); + kmem_free_wakeup(exec_map, (vm_offset_t)imgp->image_header, + PAGE_SIZE); goto exec_fail; } imgp->vp = ndp->ni_vp; - imgp->fname = uap->fname; /* * Check file permissions (also 'opens' file) @@ -180,6 +193,12 @@ if (error) goto exec_fail_dealloc; + if (debug_execve_args && imgp->interpreted) { + printf(" target is interpreted -- recursive pass\n"); + printf(" interpreter: %s\n", imgp->interpreter_name); + print_execve_args(args); + } + /* * If the current process has a special image activator it * wants to try first, call it. For example, emulating shell @@ -238,7 +257,7 @@ if (p->p_sysent->sv_fixup) (*p->p_sysent->sv_fixup)(&stack_base, imgp); else - suword(--stack_base, imgp->argc); + suword(--stack_base, imgp->args->argc); /* * For security and other reasons, the file descriptor table cannot @@ -389,26 +408,19 @@ setregs(p, imgp->entry_addr, (u_long)(uintptr_t)stack_base, imgp->ps_strings); - /* - * The syscall result is returned in registers to the new program. - * Linux will register %edx as an atexit function and we must be - * sure to set it to 0. XXX - */ - uap->sysmsg_result64 = 0; - /* Free any previous argument cache */ if (p->p_args && --p->p_args->ar_ref == 0) FREE(p->p_args, M_PARGS); p->p_args = NULL; /* Cache arguments if they fit inside our allowance */ - i = imgp->endargs - imgp->stringbase; + i = imgp->args->begin_envv - imgp->args->begin_argv; if (ps_arg_cache_limit >= i + sizeof(struct pargs)) { MALLOC(p->p_args, struct pargs *, sizeof(struct pargs) + i, M_PARGS, M_WAITOK); p->p_args->ar_ref = 1; p->p_args->ar_length = i; - bcopy(imgp->stringbase, p->p_args->ar_args, i); + bcopy(imgp->args->begin_argv, p->p_args->ar_args, i); } exec_fail_dealloc: @@ -419,9 +431,9 @@ if (imgp->firstpage) exec_unmap_first_page(imgp); - if (imgp->stringbase != NULL) - kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, - ARG_MAX + PAGE_SIZE); + if (imgp->image_header != NULL) + kmem_free_wakeup(exec_map, (vm_offset_t)imgp->image_header, + PAGE_SIZE); if (imgp->vp) { NDFREE(ndp, NDF_ONLY_PNBUF); @@ -444,6 +456,39 @@ } } +/* + * execve() system call. + */ +int +execve(struct execve_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + struct image_args args; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_FOLLOW | CNP_SAVENAME, + UIO_USERSPACE, uap->fname, td); + + error = exec_copyin_args(&args, uap->fname, PATH_USERSPACE, + uap->argv, uap->envv); + if (error) + return (error); + + error = kern_execve(&nd, &args); + + exec_free_args(&args); + + /* + * The syscall result is returned in registers to the new program. + * Linux will register %edx as an atexit function and we must be + * sure to set it to 0. XXX + */ + uap->sysmsg_result64 = 0; + + return (error); +} + int exec_map_first_page(struct image_params *imgp) { @@ -572,70 +617,97 @@ * address space into the temporary string buffer. */ int -exec_extract_strings(imgp) - struct image_params *imgp; +exec_copyin_args(struct image_args *args, char *fname, + enum exec_path_segflg segflg, char **argv, char **envv) { - char **argv, **envv; char *argp, *envp; - int error; + int error = 0; size_t length; + args->buf = (char *) kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX); + if (args->buf == NULL) + return (ENOMEM); + args->begin_argv = args->buf; + args->endp = args->begin_argv; + args->space = ARG_MAX; + args->argc = 0; + args->envc = 0; + + args->fname = args->buf + ARG_MAX; + /* - * extract arguments first + * Copy the file name. */ + if (segflg == PATH_SYSSPACE) { + error = copystr(fname, args->fname, PATH_MAX, &length); + } else if (segflg == PATH_USERSPACE) { + error = copyinstr(fname, args->fname, PATH_MAX, &length); + } - argv = imgp->uap->argv; + /* + * extract argument strings + */ if (argv) { argp = (caddr_t) (intptr_t) fuword(argv); - if (argp == (caddr_t) -1) - return (EFAULT); - if (argp) - argv++; - if (imgp->argv0) - argp = imgp->argv0; - if (argp) { - do { - if (argp == (caddr_t) -1) - return (EFAULT); - if ((error = copyinstr(argp, imgp->stringp, - imgp->stringspace, &length))) { - if (error == ENAMETOOLONG) - return(E2BIG); - return (error); - } - imgp->stringspace -= length; - imgp->stringp += length; - imgp->argc++; - } while ((argp = (caddr_t) (intptr_t) fuword(argv++))); + /* + * First argument is a special case. If it is a null + * string, we must copy the file name into the string + * buffer as the first argument. This guarantees that + * the interpreter knows what file to open in the case + * that we exec an interpreted file. + */ + while ((argp = (caddr_t) (intptr_t) fuword(argv++))) { + if (argp == (caddr_t) -1) { + error = EFAULT; + goto cleanup; + } + error = copyinstr(argp, args->endp, + args->space, &length); + if (error == ENAMETOOLONG) + error = E2BIG; + if (error) + goto cleanup; + args->space -= length; + args->endp += length; + args->argc++; } } - imgp->endargs = imgp->stringp; + args->begin_envv = args->endp; /* * extract environment strings */ - envv = imgp->uap->envv; - if (envv) { while ((envp = (caddr_t) (intptr_t) fuword(envv++))) { - if (envp == (caddr_t) -1) - return (EFAULT); - if ((error = copyinstr(envp, imgp->stringp, - imgp->stringspace, &length))) { - if (error == ENAMETOOLONG) - return(E2BIG); - return (error); + if (envp == (caddr_t) -1) { + error = EFAULT; + goto cleanup; } - imgp->stringspace -= length; - imgp->stringp += length; - imgp->envc++; + error = copyinstr(envp, args->endp, args->space, + &length); + if (error == ENAMETOOLONG) + error = E2BIG; + if (error) + goto cleanup; + args->space -= length; + args->endp += length; + args->envc++; } } - return (0); +cleanup: + if (error) + exec_free_args(args); + return (error); +} + +void +exec_free_args(struct image_args *args) +{ + kmem_free_wakeup(exec_map, (vm_offset_t)args->buf, PATH_MAX + ARG_MAX); } /* @@ -644,8 +716,7 @@ * so that it can be used as the initial stack pointer. */ register_t * -exec_copyout_strings(imgp) - struct image_params *imgp; +exec_copyout_strings(struct image_params *imgp) { int argc, envc; char **vectp; @@ -661,14 +732,14 @@ arginfo = (struct ps_strings *)PS_STRINGS; szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - - roundup((ARG_MAX - imgp->stringspace), sizeof(char *)); + roundup((ARG_MAX - imgp->args->space), sizeof(char *)); /* * install sigcode */ if (szsigcode) copyout(imgp->proc->p_sysent->sv_sigcode, - ((caddr_t)arginfo - szsigcode), szsigcode); + ((caddr_t)arginfo - szsigcode), szsigcode); /* * If we have a valid auxargs ptr, prepare some room @@ -680,29 +751,30 @@ * arg and env vector sets, and 'AT_COUNT*2' is room for the * ELF Auxargs data. */ - vectp = (char **)(destp - (imgp->argc + imgp->envc + 2 + - AT_COUNT*2) * sizeof(char*)); + vectp = (char **)(destp - (imgp->args->argc + + imgp->args->envc + 2 + AT_COUNT*2) * sizeof(char*)); else /* * The '+ 2' is for the null pointers at the end of each of the * arg and env vector sets */ vectp = (char **) - (destp - (imgp->argc + imgp->envc + 2) * sizeof(char*)); + (destp - (imgp->args->argc + imgp->args->envc + 2) * + sizeof(char*)); /* * vectp also becomes our initial stack base */ stack_base = (register_t *)vectp; - stringp = imgp->stringbase; - argc = imgp->argc; - envc = imgp->envc; + stringp = imgp->args->begin_argv; + argc = imgp->args->argc; + envc = imgp->args->envc; /* * Copy out strings - arguments and environment. */ - copyout(stringp, destp, ARG_MAX - imgp->stringspace); + copyout(stringp, destp, ARG_MAX - imgp->args->space); /* * Fill in "ps_strings" struct for ps, w, etc. Index: sys/imgact.h =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/imgact.h,v retrieving revision 1.3 diff -u -u -r1.3 imgact.h --- sys/imgact.h 20 Aug 2003 07:31:21 -0000 1.3 +++ sys/imgact.h 11 Nov 2003 04:26:52 -0000 @@ -39,33 +39,41 @@ #define MAXSHELLCMDLEN 128 +struct image_args { + char *buf; /* pointer to string buffer */ + char *begin_argv; /* beginning of argv in buf */ + char *begin_envv; /* beginning of envv in buf */ + char *endp; /* current `end' pointer of arg & env strings */ + char *fname; /* beginning of file name */ + int space; /* space left in arg & env buffer */ + int argc; /* count of argument strings */ + int envc; /* count of environment strings */ +}; + struct image_params { struct proc *proc; /* our process struct */ - struct execve_args *uap; /* syscall arguments */ + struct image_args *args; /* syscall arguments */ struct vnode *vp; /* pointer to vnode of file to exec */ struct vattr *attr; /* attributes of file */ const char *image_header; /* head of file to exec */ - char *stringbase; /* base address of tmp string storage */ - char *stringp; /* current 'end' pointer of tmp strings */ - char *endargs; /* end of argv vector */ - int stringspace; /* space left in tmp string storage area */ - int argc, envc; /* count of argument and environment strings */ - char *argv0; /* Replacement for argv[0] when interpreting */ unsigned long entry_addr; /* entry address of target executable */ char vmspace_destroyed; /* flag - we've blown away original vm space */ char interpreted; /* flag - this executable is interpreted */ char interpreter_name[MAXSHELLCMDLEN]; /* name of the interpreter */ void *auxargs; /* ELF Auxinfo structure pointer */ struct vm_page *firstpage; /* first page that we mapped */ - char *fname; /* pointer to filename of executable (user space) */ unsigned long ps_strings; /* PS_STRINGS for BSD/OS binaries */ }; #ifdef _KERNEL +enum exec_path_segflg {PATH_SYSSPACE, PATH_USERSPACE}; + int exec_check_permissions (struct image_params *); -int exec_extract_strings (struct image_params *); int exec_new_vmspace (struct image_params *); int exec_shell_imgact (struct image_params *); +int exec_copyin_args(struct image_args *, char *, enum exec_path_segflg, + char **, char **); +void exec_free_args(struct image_args *); #endif #endif /* !_SYS_IMGACT_H_ */ Index: sys/kern_syscall.h =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/kern_syscall.h,v retrieving revision 1.11 diff -u -u -r1.11 kern_syscall.h --- sys/kern_syscall.h 10 Nov 2003 20:57:17 -0000 1.11 +++ sys/kern_syscall.h 11 Nov 2003 06:26:56 -0000 @@ -33,6 +33,7 @@ enum dup_type {DUP_FIXED, DUP_VARIABLE}; union fcntl_dat; +struct image_args; struct mbuf; struct msghdr; struct nameidata; @@ -57,6 +58,11 @@ int kern_dup(enum dup_type type, int old, int new, int *res); int kern_fcntl(int fd, int cmd, union fcntl_dat *dat); int kern_fstat(int fd, struct stat *st); + +/* + * Prototypes for syscalls in kern/kern_exec.c + */ +int kern_execve(struct nameidata *nd, struct image_args *args); /* * Prototypes for syscalls in kern/kern_exit.c