Maps a file into virtual memory. This allows accessing the content of a file as simple as an array.
You need to include “C-kern/api/io/accessmode.h” (IO-Accessmode) before this file.
Memory-Mapped-File | Maps a file into virtual memory. |
Copyright | This program is free software. |
Files | |
C-kern/ | Header file of Memory-Mapped-File. |
C-kern/ | Linux specific implementation Memory-Mapped-File Linux. |
Types | |
struct mmfile_t | Exports mmfile_t. |
Functions | |
test | |
unittest_io_mmfile | Test mapping of file into memory. |
mmfile_t | Describes a memory mapped file. |
addr | The start address of the mapped memory. |
size | Size of the mapped memory. |
lifetime | |
mmfile_FREE | Static initializer for mmfile_t. |
init_mmfile | Opens a new file and maps it to memory. |
initfromio_mmfile | Maps a file referenced by sys_iochannel_t into memory. |
initsplit_mmfile | Split a memory mapping into two. |
initmove_mmfile | Moves content of sourcemfile to destmfile. |
free_mmfile | Frees all mapped memory and closes the file. |
query | |
isfree_mmfile | Returns true if mfile == mmfile_FREE. |
addr_mmfile | Returns the lowest address of the mapped memory. |
size_mmfile | Returns the size of the mapped memory. |
alignedsize_mmfile | Returns the size of the mapped memory. |
change | |
seek_mmfile | Use it to change offset of the underlying file mapped into memory. |
generic | |
genericcast_mmfile | Casts a generic object pointer into pointer to memblock_t. |
inline implementation | |
Macros | |
addr_mmfile | Implements mmfile_t.addr_mmfile. |
alignedsize_mmfile | Implements mmfile_t.alignedsize_mmfile. |
genericcast_mmfile | Implements mmfile_t.genericcast_mmfile. |
initmove_mmfile | Implements mmfile_t.initmove_mmfile. |
isfree_mmfile | Implements mmfile_t.isfree_mmfile. |
size_mmfile | Implements mmfile_t.size_mmfile. |
This program is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
© 2011 Jörg Seebohn
Header file of Memory-Mapped-File.
Linux specific implementation Memory-Mapped-File Linux.
typedef struct mmfile_t mmfile_t
Exports mmfile_t.
test | |
unittest_io_mmfile | Test mapping of file into memory. |
struct mmfile_t
Describes a memory mapped file. Memory mapped files must always be readable cause the memory must be initialized before it can be accessed. Even if you only want to write to it.
If you want to open an executable file use always accessmode <accessmode_RDEX_SHARED>.
In case a read error occurs a SIGBUS is thrown under Linux. Register special recovery handler for mmfiles => abort + read error !
Add a check function to mmfile_t which checks if memory mapping is possible ! If not then use some »read into buffer fallback operation« in some higher component !!
addr | The start address of the mapped memory. |
size | Size of the mapped memory. |
lifetime | |
mmfile_FREE | Static initializer for mmfile_t. |
init_mmfile | Opens a new file and maps it to memory. |
initfromio_mmfile | Maps a file referenced by sys_iochannel_t into memory. |
initsplit_mmfile | Split a memory mapping into two. |
initmove_mmfile | Moves content of sourcemfile to destmfile. |
free_mmfile | Frees all mapped memory and closes the file. |
query | |
isfree_mmfile | Returns true if mfile == mmfile_FREE. |
addr_mmfile | Returns the lowest address of the mapped memory. |
size_mmfile | Returns the size of the mapped memory. |
alignedsize_mmfile | Returns the size of the mapped memory. |
change | |
seek_mmfile | Use it to change offset of the underlying file mapped into memory. |
generic | |
genericcast_mmfile | Casts a generic object pointer into pointer to memblock_t. |
uint8_t * addr
The start address of the mapped memory. It is a multiple of pagesize_vm.
size_t size
Size of the mapped memory. size will be a multiple of pagesize_vm except if filesize - file_offset would be < size. In this case size is truncated to filesize - file_offset (see init_mmfile).
#define mmfile_FREE { 0, 0 }
Static initializer for mmfile_t. Makes calling of free_mmfile a no op.
int init_mmfile( /*out*/mmfile_t * mfile, const char * file_path, off_t file_offset, size_t size, accessmode_e mode, const struct directory_t * relative_to /*0 = >current_working_directory*/ )
Opens a new file and maps it to memory. Parameter file_path is considered relative to relative_to instead of the current working directory if relative_to is set to a value != 0 and file_path is a relative path
Files can be mapped into memory only page by page. If the file size is not a multiple of pagesize_vm all memory of the last mapped page which is beyond the size of the underlying file is filled with 0, and writes to that region are not written to the file.
mfile | Memory mapped file object |
file_path | Path of file to be read or written. A relatice path is relative to relative_to or the current working directory. |
file_offset | The offset of the first byte in the file whcih should be mapped. Must be a multiple of pagesize_vm. If file_offset >= filesize then ENODATA is returned => Files with length 0 always generate ENODATA error. |
size | The number of bytes which should be mapped. The mapping is always done in chunks of pagesize_vm. size (in case it is != 0) is increased until it is a multiple of pagesize_vm. If file_offset + size > filesize then size is silently truncated (file_soffset + size == filesize). If size is set to 0 then this means to map the whole file starting from file_offset. If the file is bigger than could be mapped into memory ENOMEM is returned. |
relative_to | If this parameter is != 0 and file_path is a relative path then file_path is considered relative to the path determined by this parameter. |
mode | Determines if the file is opened for reading or (reading and writing). Allowed values are accessmode_READ, accessmode_RDWR_PRIVATE and accessmode_RDWR_SHARED. |
int initfromio_mmfile( /*out*/mmfile_t * mfile, sys_iochannel_t fd, off_t file_offset, size_t size, accessmode_e mode )
Maps a file referenced by sys_iochannel_t into memory. The function does the same as init_mmfile except it does not open a file but takes a file descriptor to the already opened file. The file must always be opened with read access and also write access in case mode contains accessmode_WRITE.
If the file_offset + size is bigger than the size of the underlying file accessing the memory which has no file backing is undefinded. The operating system creates a bus error exception in cases where a whole memory page has no backing file object. If the size is set to 0 no mapping is done at all and mmfile_t is initialized with a 0 (<memblock_FREE>).
int initsplit_mmfile( /*out*/mmfile_t * destheadmfile, /*out*/mmfile_t * desttailmfile, size_t headsize, mmfile_t * sourcemfile )
Split a memory mapping into two. After return destheadmfile maps the first headsize bytes. headsize must be a multiple of pagesize_vm. desttailmfile maps the last (size_mmfile(sourcemfile)-headsize) bytes. sourcemfile is set to mmfile_FREE if it is not equal to destheadmfile or desttailmfile.
void initmove_mmfile( /*out*/mmfile_t * restrict destmfile, mmfile_t * restrict sourcemfile )
Moves content of sourcemfile to destmfile. sourcemfile is also reset to mmfile_FREE.
bool isfree_mmfile( const mmfile_t * mfile )
Returns true if mfile == mmfile_FREE.
uint8_t * addr_mmfile( const mmfile_t * mfile )
Returns the lowest address of the mapped memory. The memory is always mapped in chunks of pagesize_vm. The memory which can be accessed is at least [addr_mmfile .. <addr_mmfile>+<size_mmfile>].
size_t size_mmfile( const mmfile_t * mfile )
Returns the size of the mapped memory. The memory which corresponds to the underlying file is exactly [addr_mmfile .. <addr_mmfile>+<size_mmfile>].
size_t alignedsize_mmfile( const mmfile_t * mfile )
Returns the size of the mapped memory. This value is a multiple of pagesize_vm and it is >= size_mmfile. The mapped memory region is [addr_mmfile .. <addr_mmfile>+<alignedsize_mmfile>] but only [addr_mmfile .. <addr_mmfile>+<size_mmfile>] corresponds to the underlying file.
int seek_mmfile( mmfile_t * mfile, sys_iochannel_t fd, off_t file_offset, accessmode_e mode )
Use it to change offset of the underlying file mapped into memory. The file_offset must be a multiple of pagesize_vm -- see also initfromio_mmfile.
If size_file(fd) | file_offset (see file_t.size_file) is smaller than the value returned by size_mmfile accessing outside the memory address range can result in a SIGBUS (see initfromio_mmfile). The solution is to handle the size on a higher level after a change of the file offset. |
mmfile_t * genericcast_mmfile( void * obj, IDNAME nameprefix, TYPEQUALIFIER qualifier )
Casts a generic object pointer into pointer to memblock_t. Set qual to const if you want to cast a const pointer. The object must have two data members with access path “obj->nameprefix##addr” and “obj->nameprefix##size” of the same type as mmfile_t and in the same order.
Macros | |
addr_mmfile | Implements mmfile_t.addr_mmfile. |
alignedsize_mmfile | Implements mmfile_t.alignedsize_mmfile. |
genericcast_mmfile | Implements mmfile_t.genericcast_mmfile. |
initmove_mmfile | Implements mmfile_t.initmove_mmfile. |
isfree_mmfile | Implements mmfile_t.isfree_mmfile. |
size_mmfile | Implements mmfile_t.size_mmfile. |
#define addr_mmfile( mfile ) ((mfile)->addr)
Implements mmfile_t.addr_mmfile.
#define alignedsize_mmfile( mfile ) ((size_mmfile(mfile) + (pagesize_vm()-1)) & ~(pagesize_vm()-1))
Implements mmfile_t.alignedsize_mmfile.
#define genericcast_mmfile( obj, nameprefix, qualifier ) ( __extension__ ({ typeof(obj) _obj = (obj) ; static_assert( sizeof(_obj->nameprefix##addr) == sizeof(((mmfile_t*)0)->addr) && 0 == offsetof(mmfile_t, addr), && (typeof(_obj->nameprefix##addr)*)0 == (uint8_t**)0 && sizeof(_obj->nameprefix##size) == sizeof(((mmfile_t*)0)->size) && offsetof(mmfile_t, size) == ((uintptr_t)&_obj->nameprefix##size) -((uintptr_t)&_obj->nameprefix##addr) && (typeof(_obj->nameprefix##size)*)0 == (size_t**)0 "structure is compatible") ; (qualifier mmfile_t *)(&_obj->nameprefix##addr) ; }))
Implements mmfile_t.genericcast_mmfile.
#define initmove_mmfile( destmfile, sourcemfile ) do { mmfile_t * _sourcemfile = (sourcemfile); *(destmfile) = *(_sourcemfile); *(_sourcemfile) = (mmfile_t) mmfile_FREE; } while (0)
Implements mmfile_t.initmove_mmfile.
#define isfree_mmfile( mfile ) (0 == addr_mmfile(mfile) && 0 == size_mmfile(mfile))
Implements mmfile_t.isfree_mmfile.
#define size_mmfile( mfile ) ((mfile)->size)
Implements mmfile_t.size_mmfile.
Exports mmfile_t.
typedef struct mmfile_t mmfile_t
Describes a memory mapped file.
struct mmfile_t
Test mapping of file into memory.
int unittest_io_mmfile( void )
The start address of the mapped memory.
uint8_t * addr
Size of the mapped memory.
size_t size
Static initializer for mmfile_t.
#define mmfile_FREE { 0, 0 }
Opens a new file and maps it to memory.
int init_mmfile( /*out*/mmfile_t * mfile, const char * file_path, off_t file_offset, size_t size, accessmode_e mode, const struct directory_t * relative_to /*0 = >current_working_directory*/ )
Maps a file referenced by sys_iochannel_t into memory.
int initfromio_mmfile( /*out*/mmfile_t * mfile, sys_iochannel_t fd, off_t file_offset, size_t size, accessmode_e mode )
Choose Posix file descriptor type.
#define sys_iochannel_t int
Split a memory mapping into two.
int initsplit_mmfile( /*out*/mmfile_t * destheadmfile, /*out*/mmfile_t * desttailmfile, size_t headsize, mmfile_t * sourcemfile )
Moves content of sourcemfile to destmfile.
void initmove_mmfile( /*out*/mmfile_t * restrict destmfile, mmfile_t * restrict sourcemfile )
Frees all mapped memory and closes the file.
int free_mmfile( mmfile_t * mfile )
Returns true if mfile == mmfile_FREE.
bool isfree_mmfile( const mmfile_t * mfile )
Returns the lowest address of the mapped memory.
uint8_t * addr_mmfile( const mmfile_t * mfile )
Returns the size of the mapped memory.
size_t size_mmfile( const mmfile_t * mfile )
Returns the size of the mapped memory.
size_t alignedsize_mmfile( const mmfile_t * mfile )
Use it to change offset of the underlying file mapped into memory.
int seek_mmfile( mmfile_t * mfile, sys_iochannel_t fd, off_t file_offset, accessmode_e mode )
Casts a generic object pointer into pointer to memblock_t.
mmfile_t * genericcast_mmfile( void * obj, IDNAME nameprefix, TYPEQUALIFIER qualifier )
Describes memory block.
struct memblock_t
Implements mmfile_t.addr_mmfile.
#define addr_mmfile( mfile ) ((mfile)->addr)
Implements mmfile_t.alignedsize_mmfile.
#define alignedsize_mmfile( mfile ) ((size_mmfile(mfile) + (pagesize_vm()-1)) & ~(pagesize_vm()-1))
Implements mmfile_t.genericcast_mmfile.
#define genericcast_mmfile( obj, nameprefix, qualifier ) ( __extension__ ({ typeof(obj) _obj = (obj) ; static_assert( sizeof(_obj->nameprefix##addr) == sizeof(((mmfile_t*)0)->addr) && 0 == offsetof(mmfile_t, addr), && (typeof(_obj->nameprefix##addr)*)0 == (uint8_t**)0 && sizeof(_obj->nameprefix##size) == sizeof(((mmfile_t*)0)->size) && offsetof(mmfile_t, size) == ((uintptr_t)&_obj->nameprefix##size) -((uintptr_t)&_obj->nameprefix##addr) && (typeof(_obj->nameprefix##size)*)0 == (size_t**)0 "structure is compatible") ; (qualifier mmfile_t *)(&_obj->nameprefix##addr) ; }))
Implements mmfile_t.initmove_mmfile.
#define initmove_mmfile( destmfile, sourcemfile ) do { mmfile_t * _sourcemfile = (sourcemfile); *(destmfile) = *(_sourcemfile); *(_sourcemfile) = (mmfile_t) mmfile_FREE; } while (0)
Implements mmfile_t.isfree_mmfile.
#define isfree_mmfile( mfile ) (0 == addr_mmfile(mfile) && 0 == size_mmfile(mfile))
Implements mmfile_t.size_mmfile.
#define size_mmfile( mfile ) ((mfile)->size)
Returns the virtual memory page size supported by the underlying system.
uint32_t pagesize_vm( void )
Returns the size in bytes of the file.
int size_file( const file_t fileobj, /*out*/off_t * file_size )