|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Mach Operating System ! 24: * Copyright (c) 1987 Carnegie-Mellon University ! 25: * All rights reserved. The CMU software License Agreement specifies ! 26: * the terms and conditions for use and redistribution. ! 27: */ ! 28: ! 29: /* ! 30: */ ! 31: #include <mach_nbc.h> ! 32: #include <meta_features.h> ! 33: ! 34: #include <kern/task.h> ! 35: #include <kern/thread.h> ! 36: #include <mach/time_value.h> ! 37: #include <mach/vm_param.h> ! 38: #include <mach/vm_prot.h> ! 39: #include <mach/port.h> ! 40: ! 41: #include <sys/param.h> ! 42: #include <sys/systm.h> ! 43: #include <sys/dir.h> ! 44: #include <sys/namei.h> ! 45: #include <sys/proc.h> ! 46: #include <sys/vm.h> ! 47: #include <sys/file.h> ! 48: #include <sys/vnode.h> ! 49: #include <sys/buf.h> ! 50: #include <sys/mount.h> ! 51: #include <sys/trace.h> ! 52: #include <sys/kernel.h> ! 53: ! 54: #include <kern/kalloc.h> ! 55: #include <kern/parallel.h> ! 56: #include <kern/mapfs.h> ! 57: #include <vm/vm_map.h> ! 58: #include <vm/vm_kern.h> ! 59: ! 60: #include <machine/spl.h> ! 61: #include <mach/shared_memory_server.h> ! 62: ! 63: useracc(addr, len, prot) ! 64: caddr_t addr; ! 65: u_int len; ! 66: int prot; ! 67: { ! 68: return (vm_map_check_protection( ! 69: current_map(), ! 70: trunc_page(addr), round_page(addr+len), ! 71: prot == B_READ ? VM_PROT_READ : VM_PROT_WRITE)); ! 72: } ! 73: ! 74: vslock(addr, len) ! 75: caddr_t addr; ! 76: int len; ! 77: { ! 78: vm_map_wire(current_map(), trunc_page(addr), ! 79: round_page(addr+len), ! 80: VM_PROT_READ | VM_PROT_WRITE ,FALSE); ! 81: } ! 82: ! 83: vsunlock(addr, len, dirtied) ! 84: caddr_t addr; ! 85: int len; ! 86: int dirtied; ! 87: { ! 88: pmap_t pmap; ! 89: #if FIXME /* [ */ ! 90: vm_page_t pg; ! 91: #endif /* FIXME ] */ ! 92: vm_offset_t vaddr, paddr; ! 93: ! 94: #if FIXME /* [ */ ! 95: if (dirtied) { ! 96: pmap = get_task_pmap(current_task()); ! 97: for (vaddr = trunc_page(addr); vaddr < round_page(addr+len); ! 98: vaddr += PAGE_SIZE) { ! 99: paddr = pmap_extract(pmap, vaddr); ! 100: pg = PHYS_TO_VM_PAGE(paddr); ! 101: vm_page_set_modified(pg); ! 102: } ! 103: } ! 104: #endif /* FIXME ] */ ! 105: #ifdef lint ! 106: dirtied++; ! 107: #endif /* lint */ ! 108: vm_map_unwire(current_map(), trunc_page(addr), ! 109: round_page(addr+len), FALSE); ! 110: } ! 111: ! 112: #if defined(sun) || BALANCE || defined(m88k) ! 113: #else /*defined(sun) || BALANCE || defined(m88k)*/ ! 114: subyte(addr, byte) ! 115: void * addr; ! 116: int byte; ! 117: { ! 118: char character; ! 119: ! 120: character = (char)byte; ! 121: return (copyout((void *)&(character), addr, sizeof(char)) == 0 ? 0 : -1); ! 122: } ! 123: ! 124: suibyte(addr, byte) ! 125: void * addr; ! 126: int byte; ! 127: { ! 128: char character; ! 129: ! 130: character = (char)byte; ! 131: return (copyout((void *) &(character), addr, sizeof(char)) == 0 ? 0 : -1); ! 132: } ! 133: ! 134: int fubyte(addr) ! 135: void * addr; ! 136: { ! 137: unsigned char byte; ! 138: ! 139: if (copyin(addr, (void *) &byte, sizeof(char))) ! 140: return(-1); ! 141: return(byte); ! 142: } ! 143: ! 144: int fuibyte(addr) ! 145: void * addr; ! 146: { ! 147: unsigned char byte; ! 148: ! 149: if (copyin(addr, (void *) &(byte), sizeof(char))) ! 150: return(-1); ! 151: return(byte); ! 152: } ! 153: ! 154: suword(addr, word) ! 155: void * addr; ! 156: long word; ! 157: { ! 158: return (copyout((void *) &word, addr, sizeof(int)) == 0 ? 0 : -1); ! 159: } ! 160: ! 161: long fuword(addr) ! 162: void * addr; ! 163: { ! 164: long word; ! 165: ! 166: if (copyin(addr, (void *) &word, sizeof(int))) ! 167: return(-1); ! 168: return(word); ! 169: } ! 170: ! 171: /* suiword and fuiword are the same as suword and fuword, respectively */ ! 172: ! 173: suiword(addr, word) ! 174: void * addr; ! 175: long word; ! 176: { ! 177: return (copyout((void *) &word, addr, sizeof(int)) == 0 ? 0 : -1); ! 178: } ! 179: ! 180: long fuiword(addr) ! 181: void * addr; ! 182: { ! 183: long word; ! 184: ! 185: if (copyin(addr, (void *) &word, sizeof(int))) ! 186: return(-1); ! 187: return(word); ! 188: } ! 189: #endif /* defined(sun) || BALANCE || defined(m88k) || defined(i386) */ ! 190: ! 191: int ! 192: swapon() ! 193: { ! 194: return(EOPNOTSUPP); ! 195: } ! 196: ! 197: thread_t procdup( ! 198: struct proc *child, ! 199: struct proc *parent) ! 200: { ! 201: thread_t thread; ! 202: task_t task; ! 203: kern_return_t result; ! 204: ! 205: if (parent->task == kernel_task) ! 206: result = task_create_local(TASK_NULL, FALSE, FALSE, &task); ! 207: else ! 208: result = task_create_local(parent->task, TRUE, FALSE, &task); ! 209: if (result != KERN_SUCCESS) ! 210: printf("fork/procdup: task_create failed. Code: 0x%x\n", result); ! 211: child->task = task; ! 212: /* task->proc = child; */ ! 213: set_bsdtask_info(task, child); ! 214: ! 215: task_deallocate(task); // extra ref for convert_task_to_port() ! 216: ! 217: result = thread_create(task, &thread); ! 218: if (result != KERN_SUCCESS) ! 219: printf("fork/procdup: thread_create failed. Code: 0x%x\n", result); ! 220: act_deallocate(thread); ! 221: ! 222: #if FIXME /* [ */ ! 223: thread_deallocate(thread); // extra ref ! 224: ! 225: /* ! 226: * Don't need to lock thread here because it can't ! 227: * possibly execute and no one else knows about it. ! 228: */ ! 229: /* compute_priority(thread, FALSE); */ ! 230: #endif /* ] */ ! 231: return(thread); ! 232: } ! 233: ! 234: kern_return_t pid_for_task(t, x) ! 235: mach_port_t t; ! 236: int *x; ! 237: { ! 238: struct proc * p; ! 239: task_t t1; ! 240: extern task_t port_name_to_task(mach_port_t t); ! 241: int pid = -1; ! 242: kern_return_t err; ! 243: ! 244: t1 = port_name_to_task(t); ! 245: ! 246: if (t1 == TASK_NULL) { ! 247: err = KERN_FAILURE; ! 248: } else { ! 249: p = get_bsdtask_info(t1); ! 250: if (p) { ! 251: pid = p->p_pid; ! 252: err = KERN_SUCCESS; ! 253: } else { ! 254: err = KERN_FAILURE; ! 255: } ! 256: } ! 257: task_deallocate(t1); ! 258: (void) copyout((char *) &pid, (char *) x, sizeof(*x)); ! 259: return err; ! 260: } ! 261: ! 262: /* ! 263: * Routine: task_by_unix_pid ! 264: * Purpose: ! 265: * Get the task port for another "process", named by its ! 266: * process ID on the same host as "target_task". ! 267: * ! 268: * Only permitted to privileged processes, or processes ! 269: * with the same user ID. ! 270: */ ! 271: kern_return_t task_for_pid(target_tport, pid, t) ! 272: mach_port_t target_tport; ! 273: int pid; ! 274: mach_port_t *t; ! 275: { ! 276: struct proc *p; ! 277: struct proc *p1; ! 278: task_t t1; ! 279: mach_port_t tret; ! 280: extern task_t port_name_to_task(mach_port_t tp); ! 281: void * sright; ! 282: ! 283: unix_master(); ! 284: t1 = port_name_to_task(target_tport); ! 285: if (t1 == TASK_NULL) { ! 286: *t = TASK_NULL; ! 287: unix_release(); ! 288: return (KERN_FAILURE); ! 289: } ! 290: ! 291: p1 = get_bsdtask_info(t1); ! 292: if ( ! 293: ((p = pfind(pid)) != (struct proc *) 0) ! 294: && (p1 != (struct proc *) 0) ! 295: && ((p->p_ucred->cr_uid == p1->p_ucred->cr_uid) ! 296: || !(suser(p1->p_ucred, &p1->p_acflag))) ! 297: && (p->p_stat != SZOMB) ! 298: ) { ! 299: task_deallocate(t1); ! 300: if (p->task != TASK_NULL) { ! 301: task_reference(p->task); ! 302: #if 0 ! 303: sright = retrieve_task_self_fast(p->task); ! 304: #else ! 305: sright = convert_task_to_port(p->task); ! 306: #endif ! 307: tret = ipc_port_copyout_send(sright, get_task_ipcspace(current_task())); ! 308: } else ! 309: tret = MACH_PORT_NULL; ! 310: (void ) copyout((char *)&tret, (char *) t, sizeof(mach_port_t)); ! 311: /* compatibility with NeXT 2.0 debuggers, launchers */ ! 312: if (suser(p->p_ucred, &p->p_acflag)) { ! 313: /* don't set it for anyone; could exec a careless nameserver */ ! 314: struct proc *p=get_bsdtask_info(current_task()); ! 315: ! 316: if (p) ! 317: p->p_debugger = 1; ! 318: } ! 319: unix_release(); ! 320: return(KERN_SUCCESS); ! 321: } ! 322: task_deallocate(t1); ! 323: tret = MACH_PORT_NULL; ! 324: (void) copyout((char *) &tret, (char *) t, sizeof(mach_port_t)); ! 325: ! 326: unix_release(); ! 327: return(KERN_FAILURE); ! 328: } ! 329: ! 330: #if 0 ! 331: /* ! 332: * Routine: task_by_pid ! 333: * Purpose: ! 334: * Trap form of "task_by_unix_pid"; soon to be eliminated. ! 335: */ ! 336: mach_port_t task_by_pid(pid) ! 337: int pid; ! 338: { ! 339: task_t self = current_task(); ! 340: port_t t = PORT_NULL; ! 341: task_t result_task; ! 342: ! 343: if (task_by_unix_pid(self, pid, &result_task) == KERN_SUCCESS) { ! 344: t = convert_task_to_port(result_task); ! 345: if (t != PORT_NULL) ! 346: object_copyout(self, t, MSG_TYPE_PORT, &t); ! 347: } ! 348: ! 349: return(t); ! 350: } ! 351: #endif /* 0 */ ! 352: ! 353: ! 354: ! 355: ! 356: int ! 357: load_shared_file( ! 358: caddr_t mapped_file_addr, ! 359: u_long mapped_file_size, ! 360: caddr_t *base_address, ! 361: int map_cnt, ! 362: sf_mapping_t *mappings, ! 363: char *filename, ! 364: int *flags) ! 365: { ! 366: struct vnode *vp = 0; ! 367: struct nameidata nd, *ndp; ! 368: struct proc *p = current_proc(); ! 369: register int error; ! 370: kern_return_t kr; ! 371: ! 372: struct vattr vattr; ! 373: void *pager_cport; ! 374: void *object; ! 375: void *file_object; ! 376: sf_mapping_t *map_list; ! 377: caddr_t local_base; ! 378: int local_flags; ! 379: kern_return_t kret; ! 380: ! 381: ndp = &nd; ! 382: ! 383: ! 384: ! 385: unix_master(); ! 386: ! 387: /* Retrieve the base address */ ! 388: if (copyin(base_address, &local_base, sizeof (caddr_t))) { ! 389: error = EINVAL; ! 390: goto lsf_bailout; ! 391: } ! 392: if (copyin(flags, &local_flags, sizeof (int))) { ! 393: error = EINVAL; ! 394: goto lsf_bailout; ! 395: } ! 396: kret = kmem_alloc(kernel_map, &map_list, ! 397: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 398: if (kret != KERN_SUCCESS) { ! 399: error = ENOMEM; ! 400: goto lsf_bailout; ! 401: } ! 402: ! 403: if (copyin(mappings, map_list, (map_cnt*sizeof(sf_mapping_t)))) { ! 404: kmem_free(kernel_map, map_list, ! 405: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 406: error = EINVAL; ! 407: goto lsf_bailout; ! 408: } ! 409: ! 410: /* ! 411: * Get a vnode for the target file ! 412: */ ! 413: NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, ! 414: filename, p); ! 415: ! 416: if ((error = namei(ndp))) { ! 417: error = EINVAL; ! 418: kmem_free(kernel_map, map_list, ! 419: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 420: goto lsf_bailout; ! 421: } ! 422: ! 423: vp = ndp->ni_vp; ! 424: ! 425: if (vp->v_type != VREG) { ! 426: error = EINVAL; ! 427: kmem_free(kernel_map, map_list, ! 428: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 429: VOP_UNLOCK(vp, 0, p); ! 430: goto lsf_bailout; ! 431: } ! 432: ! 433: if (!vp->v_vm_info) { ! 434: vm_info_init(vp); ! 435: } ! 436: ! 437: if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) { ! 438: VOP_UNLOCK(vp, 0, p); ! 439: kmem_free(kernel_map, map_list, ! 440: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 441: goto lsf_bailout; ! 442: } ! 443: ! 444: ! 445: if(pager_cport = (void *)vnode_pager_lookup(vp, vp->v_vm_info->pager)) { ! 446: if(file_object = (void *)vm_object_lookup(pager_cport)) { ! 447: error = 0; ! 448: } else { ! 449: VOP_UNLOCK(vp, 0, p); ! 450: kmem_free(kernel_map, map_list, ! 451: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 452: error = EINVAL; ! 453: goto lsf_bailout; ! 454: } ! 455: } else { ! 456: VOP_UNLOCK(vp, 0, p); ! 457: error = EINVAL; ! 458: goto lsf_bailout; ! 459: } ! 460: ! 461: vp->v_vm_info->vnode_size = vattr.va_size; ! 462: ! 463: if(vattr.va_size != mapped_file_size) { ! 464: VOP_UNLOCK(vp, 0, p); ! 465: kmem_free(kernel_map, map_list, ! 466: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 467: error = EINVAL; ! 468: goto lsf_bailout; ! 469: } ! 470: ! 471: VREF(vp); ! 472: if(copyin_shared_file(mapped_file_addr, mapped_file_size, &local_base, ! 473: map_cnt, map_list, file_object, &local_flags)) { ! 474: vrele(vp); ! 475: error = EINVAL; ! 476: } else { ! 477: copyout(&local_flags, flags, sizeof (int)); ! 478: copyout(&local_base, base_address, sizeof (caddr_t)); ! 479: if (local_flags & SF_PREV_LOADED) { ! 480: vrele(vp); ! 481: } ! 482: } ! 483: kmem_free(kernel_map, map_list, ! 484: (vm_size_t)(map_cnt*sizeof(sf_mapping_t))); ! 485: VOP_UNLOCK(vp, 0, p); ! 486: ! 487: lsf_bailout: ! 488: /* deallocate any remaining remnants of mapped file sent by caller */ ! 489: vm_deallocate(current_map(), mapped_file_addr, mapped_file_size); ! 490: unix_release(); ! 491: return error; ! 492: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.