1/* 2 * Copyright (c) 1993, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $Id: kern_exec.c,v 1.73 1998/01/06 05:15:34 dyson Exp $ |
27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/sysproto.h> 32#include <sys/signalvar.h> 33#include <sys/kernel.h> 34#include <sys/mount.h> --- 14 unchanged lines hidden (view full) --- 49#include <sys/vnode.h> 50#include <sys/buf.h> 51 52#include <vm/vm.h> 53#include <vm/vm_param.h> 54#include <vm/vm_prot.h> 55#include <sys/lock.h> 56#include <vm/pmap.h> |
57#include <vm/vm_page.h> |
58#include <vm/vm_map.h> 59#include <vm/vm_kern.h> 60#include <vm/vm_extern.h> 61#include <vm/vm_object.h> 62#include <vm/vm_zone.h> |
63#include <vm/vm_pager.h> 64#include <vm/vm_pageout.h> |
65 66#include <machine/reg.h> 67 68static int *exec_copyout_strings __P((struct image_params *)); 69 |
70static int exec_check_permissions __P((struct image_params *)); 71static int exec_map_first_page __P((struct image_params *)); 72static void exec_unmap_first_page __P((struct image_params *)); |
73 74/* 75 * XXX trouble here if sizeof(caddr_t) != sizeof(int), other parts 76 * of the sysctl code also assumes this, and sizeof(int) == sizeof(long). 77 */ 78static struct ps_strings *ps_strings = PS_STRINGS; 79SYSCTL_INT(_kern, KERN_PS_STRINGS, ps_strings, 0, &ps_strings, 0, ""); 80 --- 33 unchanged lines hidden (view full) --- 114 imgp = &image_params; 115 116 /* 117 * Initialize part of the common data 118 */ 119 imgp->proc = p; 120 imgp->uap = uap; 121 imgp->attr = &attr; |
122 imgp->argc = imgp->envc = 0; 123 imgp->argv0 = NULL; 124 imgp->entry_addr = 0; 125 imgp->vmspace_destroyed = 0; 126 imgp->interpreted = 0; 127 imgp->interpreter_name[0] = '\0'; 128 imgp->auxargs = NULL; |
129 imgp->vp = NULL; 130 imgp->firstpage = NULL; |
131 132 /* 133 * Allocate temporary demand zeroed space for argument and 134 * environment strings 135 */ |
136 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + PAGE_SIZE); |
137 if (imgp->stringbase == NULL) { 138 error = ENOMEM; 139 goto exec_fail; 140 } 141 imgp->stringp = imgp->stringbase; 142 imgp->stringspace = ARG_MAX; |
143 imgp->image_header = imgp->stringbase + ARG_MAX; |
144 145 /* 146 * Translate the file name. namei() returns a vnode pointer 147 * in ni_vp amoung other things. 148 */ 149 ndp = &nd; 150 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, 151 UIO_USERSPACE, uap->fname, p); 152 153interpret: 154 155 error = namei(ndp); 156 if (error) { |
157 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, 158 ARG_MAX + PAGE_SIZE); |
159 goto exec_fail; 160 } 161 162 imgp->vp = ndp->ni_vp; 163 164 /* 165 * Check file permissions (also 'opens' file) 166 */ 167 error = exec_check_permissions(imgp); 168 if (error) { 169 VOP_UNLOCK(imgp->vp, 0, p); 170 goto exec_fail_dealloc; 171 } 172 |
173 error = exec_map_first_page(imgp); |
174 VOP_UNLOCK(imgp->vp, 0, p); 175 if (error) 176 goto exec_fail_dealloc; 177 178 /* 179 * Loop through list of image activators, calling each one. 180 * If there is no match, the activator returns -1. If there 181 * is a match, but there was an error during the activation, --- 6 unchanged lines hidden (view full) --- 188 error = (*execsw[i]->ex_imgact)(imgp); 189 else 190 continue; 191 if (error == -1) 192 continue; 193 if (error) 194 goto exec_fail_dealloc; 195 if (imgp->interpreted) { |
196 exec_unmap_first_page(imgp); |
197 /* free old vnode and name buffer */ 198 vrele(ndp->ni_vp); 199 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf); 200 /* set new name to that of the interpreter */ 201 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, 202 UIO_SYSSPACE, imgp->interpreter_name, p); 203 goto interpret; 204 } --- 112 unchanged lines hidden (view full) --- 317 psignal(p, SIGTRAP); 318 319 /* clear "fork but no exec" flag, as we _are_ execing */ 320 p->p_acflag &= ~AFORK; 321 322 /* Set entry address */ 323 setregs(p, imgp->entry_addr, (u_long)stack_base); 324 |
325exec_fail_dealloc: 326 |
327 /* 328 * free various allocated resources 329 */ |
330 if (imgp->firstpage) 331 exec_unmap_first_page(imgp); |
332 |
333 if (imgp->stringbase != NULL) |
334 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, 335 ARG_MAX + PAGE_SIZE); 336 |
337 if (ndp->ni_vp) { 338 vrele(ndp->ni_vp); 339 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf); 340 } 341 |
342 if (error == 0) 343 return (0); 344 |
345exec_fail: 346 if (imgp->vmspace_destroyed) { 347 /* sorry, no more process anymore. exit gracefully */ 348 exit1(p, W_EXITCODE(0, SIGABRT)); 349 /* NOT REACHED */ 350 return(0); 351 } else { 352 return(error); 353 } 354} 355 |
356int 357exec_map_first_page(imgp) 358 struct image_params *imgp; 359{ 360 int s; 361 vm_page_t m; 362 vm_object_t object; 363 364 365 if (imgp->firstpage) { 366 exec_unmap_first_page(imgp); 367 } 368 369 object = imgp->vp->v_object; 370 s = splvm(); 371 372retry: 373 m = vm_page_lookup(object, 0); 374 if (m == NULL) { 375 m = vm_page_alloc(object, 0, VM_ALLOC_NORMAL); 376 if (m == NULL) { 377 VM_WAIT; 378 goto retry; 379 } 380 } else if ((m->flags & PG_BUSY) || m->busy) { 381 m->flags |= PG_WANTED; 382 tsleep(m, PVM, "execpw", 0); 383 goto retry; 384 } 385 386 m->flags |= PG_BUSY; 387 388 if ((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) { 389 int rv; 390 rv = vm_pager_get_pages(object, &m, 1, 0); 391 if (rv != VM_PAGER_OK) { 392 vm_page_protect(m, VM_PROT_NONE); 393 vm_page_deactivate(m); 394 PAGE_WAKEUP(m); 395 splx(s); 396 return EIO; 397 } 398 } 399 400 vm_page_wire(m); 401 PAGE_WAKEUP(m); 402 splx(s); 403 404 pmap_kenter((vm_offset_t) imgp->image_header, VM_PAGE_TO_PHYS(m)); 405 imgp->firstpage = m; 406 407 return 0; 408} 409 410void 411exec_unmap_first_page(imgp) 412 struct image_params *imgp; 413{ 414 if (imgp->firstpage) { 415 pmap_kremove((vm_offset_t) imgp->image_header); 416 vm_page_unwire(imgp->firstpage); 417 imgp->firstpage = NULL; 418 } 419} 420 |
421/* 422 * Destroy old address space, and allocate a new stack 423 * The new stack is only SGROWSIZ large because it is grown 424 * automatically in trap.c. 425 */ 426int 427exec_new_vmspace(imgp) 428 struct image_params *imgp; --- 17 unchanged lines hidden (view full) --- 446 vm_map_remove(map, 0, USRSTACK); 447 } else { 448 vmspace_exec(imgp->proc); 449 vmspace = imgp->proc->p_vmspace; 450 map = &vmspace->vm_map; 451 } 452 453 /* Allocate a new stack */ |
454 error = vm_map_insert(&vmspace->vm_map, NULL, 0, 455 (vm_offset_t) stack_addr, (vm_offset_t) USRSTACK, 456 VM_PROT_ALL, VM_PROT_ALL, 0); |
457 if (error) |
458 return (error); |
459 460 vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT; 461 462 /* Initialize maximum stack address */ 463 vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ; 464 465 return(0); 466} --- 235 unchanged lines hidden --- |