#include "../file.h" #include "../mapping.h" #include #include #include #include #include #include #include #include #include extern kern_status_t fs_msg_map( xpc_context_t *xpc, const xpc_endpoint_t *sender, int prot, int flags, int *out_err, kern_handle_t *out_vmo, void *arg) { struct fs_context *ctx = arg; struct fs_file *f = fs_context_get_file(ctx, sender->e_port); if (!f) { *out_err = EBADF; return KERN_OK; } struct file_mapping *mapping = fs_context_alloc(ctx, sizeof *mapping); if (!mapping) { *out_err = ENOMEM; return KERN_OK; } kern_logf("mapping file %s", f->f_dent->d_name); vm_prot_t vm_prot = VM_PROT_USER; if (prot & PROT_READ) { vm_prot |= VM_PROT_READ; } if (prot & PROT_WRITE) { vm_prot |= VM_PROT_WRITE; } if (prot & PROT_EXEC) { vm_prot |= VM_PROT_EXEC; } kern_handle_t vmo = KERN_HANDLE_INVALID; kern_status_t status = vm_controller_create_object( fs_context_get_vm_controller(ctx), f->f_dent->d_name, strlen(f->f_dent->d_name), (equeue_key_t)mapping, f->f_inode->i_size, vm_prot, &vmo); if (status != KERN_OK) { fs_context_free(ctx, mapping); *out_err = __errno_from_kern_status(status); return KERN_OK; } mapping->m_file = f; mapping->m_file_offset = 0; kern_handle_duplicate(vmo, &mapping->m_vmo); queue_push_back(&f->f_mappings, &mapping->m_entry); *out_err = SUCCESS; *out_vmo = vmo; return KERN_OK; }