1 /* 2 * File access convenience functions. 3 * 4 * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <ipc/cap_alloc.h> 23 #include <ipc/mem_ipc.h> 24 25 #include "dataspace_client.h" 26 #include "opener_client.h" 27 #include "opener_context_client.h" 28 #include "mapped_file_client.h" 29 30 #include "file.h" 31 32 33 34 /* Release resources for the given file. */ 35 36 void file_close(file_t *file) 37 { 38 if (l4_is_valid_cap(file->ref)) 39 ipc_cap_free_um(file->ref); 40 41 if (file->memory != NULL) 42 ipc_detach_dataspace(file->memory); 43 44 file_init(file); 45 } 46 47 /* Initialise a file structure for a context obtained from the given server. */ 48 49 long file_context(file_t *file, l4_cap_idx_t server) 50 { 51 client_Opener opener(server); 52 unsigned long size, flags; 53 long err; 54 55 file_init(file); 56 err = opener.context(&file->ref); 57 58 if (err) 59 return err; 60 61 client_Dataspace context_ds(file->ref); 62 63 err = context_ds.info(&size, &flags); 64 65 if (err) 66 return err; 67 68 return ipc_attach_dataspace(file->ref, size, (void **) &file->memory); 69 } 70 71 /* Initialise the given file structure. */ 72 73 void file_init(file_t *file) 74 { 75 file->memory = NULL; 76 file->ref = L4_INVALID_CAP; 77 } 78 79 /* Map a region of the given file to a memory region. */ 80 81 long file_mmap(file_t *file, offset_t position, offset_t length) 82 { 83 client_MappedFile mapped_file(file->ref); 84 long err = mapped_file.mmap(position, length, &file->start_pos, &file->end_pos, &file->data_end); 85 86 if (err) 87 return err; 88 89 return ipc_attach_dataspace(file->ref, file->end_pos - file->start_pos, (void **) &file->memory); 90 } 91 92 /* Open a file using the given structure and context. */ 93 94 long file_open(file_t *file, file_t *context) 95 { 96 client_OpenerContext openercontext(context->ref); 97 file_init(file); 98 return openercontext.open(L4_FPAGE_RW, &file->size, &file->ref); 99 } 100 101 /* Return the amount of data in the mapped region for the given file. */ 102 103 offset_t file_populated_span(file_t *file) 104 { 105 offset_t size = file_span(file); 106 return (file->data_end < size) ? file->data_end : size; 107 } 108 109 /* Return the size of the mapped region for the given file. */ 110 111 offset_t file_span(file_t *file) 112 { 113 return file->end_pos - file->start_pos; 114 } 115 116 // vim: tabstop=2 expandtab shiftwidth=2