|
|
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.