# Features & API Reference
## Features
### Core Operations
- **File-backed memory mapping** - Map files directly into memory for fast random access
- **Positional read/write** - Read and write at specific offsets without seeking
- **Synchronization** - Flush changes to disk with sync (blocking) or async modes
- **File resize** - Truncate or extend files with automatic remapping
### Access Modes
- `read` - Read-only access
- `write` - Write-only access
- `read_write` - Full access (default)
### Mapping Options
- `shared` - Changes are visible to other processes and written to file (default)
- `private` - Copy-on-write; changes are private to this process
- `lock` - Lock pages in memory to prevent swapping
- `populate` - Prefault pages on mapping (Linux only)
- `nocache` - Disable page caching (macOS only)
- `create` - Create file if it doesn't exist
- `truncate` - Truncate existing file
### Memory Advice (madvise)
Provide hints to the kernel about access patterns:
- `normal` - No special treatment
- `random` - Expect random access pattern
- `sequential` - Expect sequential access pattern
- `willneed` - Will need these pages soon
- `dontneed` - Won't need these pages soon
## Platform Support
| Feature | Linux | macOS | FreeBSD | OpenBSD |
|---------|-------|-------|---------|---------|
| Basic mmap | Yes | Yes | Yes | Yes |
| MAP_POPULATE | Yes | No | No | No |
| MAP_NOCACHE | No | Yes | No | No |
| mlock | Yes | Yes | Yes | Yes |
| madvise | Yes | Yes | Yes | Yes |
| fallocate | Yes | ftruncate | posix_fallocate | ftruncate |
## API Reference
### open/2, open/3
```erlang
{ok, Handle} = iommap:open(Path, Options).
{ok, Handle} = iommap:open(Path, Mode, Options).
```
Opens a file for memory-mapped access.
**Arguments:**
- `Path` - File path (string or binary)
- `Mode` - Access mode: `read`, `write`, or `read_write`
- `Options` - List of options (see Mapping Options above)
**Returns:**
- `{ok, Handle}` on success
- `{error, Reason}` on failure
### close/1
```erlang
ok = iommap:close(Handle).
```
Closes the mapping and file descriptor. The handle becomes invalid after this call.
### pread/3
```erlang
{ok, Binary} = iommap:pread(Handle, Offset, Length).
```
Reads `Length` bytes starting at `Offset`. Returns a copy of the data.
**Arguments:**
- `Handle` - Memory map handle
- `Offset` - Byte offset to start reading
- `Length` - Number of bytes to read
**Returns:**
- `{ok, Binary}` containing the requested data
- `{error, out_of_bounds}` if range exceeds file size
- `{error, sigbus}` if memory access fault occurred
### pwrite/3
```erlang
ok = iommap:pwrite(Handle, Offset, Data).
```
Writes `Data` (binary or iolist) at `Offset`.
**Arguments:**
- `Handle` - Memory map handle
- `Offset` - Byte offset to start writing
- `Data` - Binary or iolist to write
**Returns:**
- `ok` on success
- `{error, out_of_bounds}` if range exceeds file size
- `{error, sigbus}` if memory access fault occurred
### sync/1, sync/2
```erlang
ok = iommap:sync(Handle).
ok = iommap:sync(Handle, Mode).
```
Flushes changes to disk.
**Arguments:**
- `Handle` - Memory map handle
- `Mode` - `sync` (blocking, default) or `async` (non-blocking)
### truncate/2
```erlang
ok = iommap:truncate(Handle, NewSize).
```
Resizes the file and remaps the memory region. Existing data beyond `NewSize` is lost.
**Arguments:**
- `Handle` - Memory map handle
- `NewSize` - New file size in bytes
### advise/4
```erlang
ok = iommap:advise(Handle, Offset, Length, Hint).
```
Provides access pattern hints to the kernel for optimization.
**Arguments:**
- `Handle` - Memory map handle
- `Offset` - Start of region
- `Length` - Length of region (0 for entire file)
- `Hint` - `normal`, `random`, `sequential`, `willneed`, or `dontneed`
### position/1
```erlang
{ok, Size} = iommap:position(Handle).
```
Returns the current size of the mapped region.
## Thread Safety
The NIF uses pthread read-write locks to ensure thread safety:
- Multiple concurrent reads are allowed
- Writes are exclusive
- Handle validity is checked under the lock
## Error Handling
Errors are returned as `{error, Reason}` tuples:
| Reason | Description |
|--------|-------------|
| `badarg` | Invalid arguments |
| `enomem` | Out of memory |
| `enoent` | File not found |
| `eacces` | Permission denied |
| `closed` | Handle already closed |
| `out_of_bounds` | Offset/length exceeds file size |
| `sigbus` | Memory access fault (file truncated externally) |
## SIGBUS Protection
The NIF installs a SIGBUS handler to protect against crashes when the underlying file is truncated externally while the mapping exists. If a SIGBUS occurs during read/write, `{error, sigbus}` is returned instead of crashing the VM.