paul@142 | 1 | = Files = |
paul@142 | 2 | |
paul@142 | 3 | Access to files is provided by a number of programs acting as components. For |
paul@142 | 4 | convenience, the component-level operations are wrapped up in a client library |
paul@142 | 5 | that aims to provide simpler, more familiar mechanisms for opening, reading, |
paul@142 | 6 | writing, and closing files, together with various other operations. |
paul@142 | 7 | |
paul@142 | 8 | <<TableOfContents(2,3)>> |
paul@142 | 9 | |
paul@142 | 10 | == Components == |
paul@142 | 11 | |
paul@142 | 12 | At the lowest level in L4Re, files are accessed via a suite of components. |
paul@142 | 13 | |
paul@142 | 14 | === Filesystems === |
paul@142 | 15 | |
paul@144 | 16 | Filesystems implement the `Filesystem` interface which provides the |
paul@144 | 17 | `open_for_user` operation: |
paul@144 | 18 | |
paul@144 | 19 | {{{ |
paul@144 | 20 | open_for_user(in sys_uid_t uid, in sys_gid_t gid, in sys_mode_t umask, |
paul@144 | 21 | out cap opener) |
paul@144 | 22 | }}} |
paul@144 | 23 | |
paul@144 | 24 | The operation yields a file opener appropriate for the given user credentials. |
paul@144 | 25 | |
paul@144 | 26 | === File Openers === |
paul@144 | 27 | |
paul@144 | 28 | File openers implement the `Opener` interface which provides the `context` |
paul@142 | 29 | operation: |
paul@142 | 30 | |
paul@142 | 31 | {{{ |
paul@142 | 32 | context(out cap context) |
paul@142 | 33 | }}} |
paul@142 | 34 | |
paul@142 | 35 | Each client program, task or thread obtains its own context because it will |
paul@142 | 36 | need its own dedicated channel for communication with the filesystem. |
paul@142 | 37 | |
paul@142 | 38 | === Contexts === |
paul@142 | 39 | |
paul@142 | 40 | A context acts as a dataspace, meaning that it can be attached to a task using |
paul@142 | 41 | a region manager and provide a buffer via a region of mapped memory that the |
paul@142 | 42 | task can write to. In the case of a context, the task will write a filesystem |
paul@142 | 43 | path indicating the file to be opened. |
paul@142 | 44 | |
paul@142 | 45 | Each context allows a client program to request access to individual files via |
paul@142 | 46 | operations provided by the `OpenerContext` interface, of which the most |
paul@142 | 47 | pertinent is the `open` operation: |
paul@142 | 48 | |
paul@142 | 49 | {{{ |
paul@142 | 50 | open(in flags_t flags, out offset_t size, out cap file) |
paul@142 | 51 | }}} |
paul@142 | 52 | |
paul@142 | 53 | Using the path information written to the context's memory region, the `open` |
paul@142 | 54 | operation will obtain a reference to a file. |
paul@142 | 55 | |
paul@142 | 56 | === Files === |
paul@142 | 57 | |
paul@142 | 58 | Files themselves act as dataspaces, meaning that they can be attached to a |
paul@142 | 59 | task using a region manager and provide their content via a region of mapped |
paul@142 | 60 | memory. Files implement the `MappedFile` interface. |
paul@142 | 61 | |
paul@142 | 62 | Control over the region of the file provided via mapped memory occurs |
paul@142 | 63 | using the `mmap` operation: |
paul@142 | 64 | |
paul@142 | 65 | {{{ |
paul@142 | 66 | mmap(in offset_t position, in offset_t length, |
paul@142 | 67 | out offset_t start_pos, out offset_t end_pos, |
paul@142 | 68 | out offset_t size) |
paul@142 | 69 | }}} |
paul@142 | 70 | |
paul@142 | 71 | Files also implement the more general `File` interface that provides the |
paul@142 | 72 | `resize` operation: |
paul@142 | 73 | |
paul@142 | 74 | {{{ |
paul@142 | 75 | resize(inout offset_t size) |
paul@142 | 76 | }}} |
paul@142 | 77 | |
paul@142 | 78 | This allows the portion of the memory region dedicated to the file's contents |
paul@142 | 79 | to be extended. |
paul@142 | 80 | |
paul@142 | 81 | == Libraries == |
paul@142 | 82 | |
paul@142 | 83 | The filesystem client library offers abstractions and a number of layers of |
paul@142 | 84 | functionality to support interaction with components and the provision of |
paul@142 | 85 | higher-level mechanisms and abstractions for file access. |
paul@142 | 86 | |
paul@142 | 87 | === Client Library === |
paul@142 | 88 | |
paul@142 | 89 | The client library provides functions somewhat resembling the traditional C |
paul@142 | 90 | library and low-level Unix interfaces for file access, and these functions are |
paul@142 | 91 | intended to support such traditional interfaces. |
paul@142 | 92 | |
paul@142 | 93 | Since files are accessed using file references, the `file_t` data structure is |
paul@142 | 94 | used to wrap such references and other relevant state. Thus, such structures |
paul@142 | 95 | can be broadly regarded as similar to the traditional `FILE` data structure. |
paul@142 | 96 | |
paul@142 | 97 | Files are opened and closed using the following functions: |
paul@142 | 98 | |
paul@142 | 99 | {{{ |
paul@142 | 100 | file_t *client_open(const char *name, flags_t flags); |
paul@142 | 101 | void client_close(file_t *file); |
paul@142 | 102 | }}} |
paul@142 | 103 | |
paul@142 | 104 | Reading and writing files involves functions resembling the traditional |
paul@142 | 105 | low-level `read` and `write` functions: |
paul@142 | 106 | |
paul@142 | 107 | {{{ |
paul@142 | 108 | offset_t client_read(file_t *file, void *buf, offset_t count); |
paul@142 | 109 | offset_t client_write(file_t *file, const void *buf, offset_t count); |
paul@142 | 110 | }}} |
paul@142 | 111 | |
paul@142 | 112 | Support for navigation in files is provided using functions resembling the |
paul@142 | 113 | traditional higher-level `fseek` and `ftell` functions: |
paul@142 | 114 | |
paul@142 | 115 | {{{ |
paul@142 | 116 | offset_t client_seek(file_t *file, offset_t offset, int whence); |
paul@142 | 117 | long client_tell(file_t *file); |
paul@142 | 118 | }}} |
paul@142 | 119 | |
paul@142 | 120 | Although the client library (and the provision of files) employs mapped |
paul@142 | 121 | memory, a function can be used to explicitly reference memory for file access: |
paul@142 | 122 | |
paul@142 | 123 | {{{ |
paul@142 | 124 | void *client_mmap(file_t *file, offset_t position, offset_t length); |
paul@142 | 125 | }}} |
paul@142 | 126 | |
paul@142 | 127 | For synchronisation purposes, either with the filesystem itself or with other |
paul@142 | 128 | users of the filesystem, a function resembling the traditional `fflush` |
paul@142 | 129 | function is provided: |
paul@142 | 130 | |
paul@142 | 131 | {{{ |
paul@142 | 132 | long client_flush(file_t *file); |
paul@142 | 133 | }}} |