The foundation provides process-local device emulation for dynamically linked Linux applications. A registered path is opened as a synthetic file descriptor, while device operations are dispatched to a userspace backend.
The foundation does not define V4L2, Android camera access, frame formats, or hardware-buffer transport. Those belong to later backends.
| Object | Application visibility | Responsibility |
|---|---|---|
| Placeholder device path | Visible | Makes directory scans discover the device |
eventfd |
Returned by open |
Blocking and readiness notification |
SOCK_SEQPACKET control connection |
Hidden | Broker commands, responses, errors, and file-descriptor passing |
memfd mappings |
Exposed through mmap |
Shared backend data |
| Session registry | Hidden | Associates descriptor aliases with one backend session |
eventfd is a readiness primitive only. It never carries device payloads,
metadata, or control messages.
The broker uses a pathname-based AF_UNIX SOCK_SEQPACKET socket. Each packet
contains one fixed-width little-endian header, at most 64 KiB of payload, and at
most four descriptors carried with SCM_RIGHTS.
- Request IDs bind every response to exactly one request.
- Received descriptors are close-on-exec and become the receiver's property.
- Malformed, truncated, mismatched, or out-of-version packets terminate the connection.
- Backend error responses fail only that request; transport errors are sticky.
- A broker that does not reply fails a control request after at most two seconds
of receive inactivity, or a
VIDEO_FRAMErequest after twenty seconds; the connection becomes terminal. - Broker disconnect writes one token to the device readiness
eventfd. The token remains readable while later operations returnEPIPE. - Device data uses
memfddescriptors; writable video staging buffers are distinct from client-mapped buffers. Device-specificmmaptranslation remains a backend responsibility.
The optional /dev/video0 broker path sends VIDEO_FRAME with a per-request
staging FD and a fixed-width little-endian description (offset, dimensions,
stride, RGB24 format, byte count). After the broker replies, the producer
copies the frame into the client-mapped buffer only if that stream is still
active, then marks it ready. A late write to a cancelled request cannot
overwrite a restarted stream's mapped buffer. QBUF and STREAMON only queue
work; STREAMOFF cancels an in-flight request, and a later stream reconnects.
The broker socket must live in a private directory and use mode 0600. The
broker must validate clients with SO_PEERCRED; abstract sockets are not used
because they do not provide filesystem permission checks.
| Operation | Required behavior |
|---|---|
open, open64, openat, openat64 and fortified aliases |
Match registered paths and create a session |
stat, lstat, fstat, fstatat, statx |
Report the configured character-device identity |
close, close_range, closefrom |
Remove aliases and tear down the final reference once |
dup, dup2, dup3, fcntl duplication commands |
Attach aliases to the same session |
fcntl status commands |
Preserve shared O_NONBLOCK behavior and close-on-exec policy |
ioctl |
Dispatch dummy descriptors; forward all other descriptors unchanged |
read, readv, pread*, write, writev, pwrite* |
Reject unsupported dummy-device I/O without consuming readiness tokens |
pthread_atfork child handler |
Close inherited dummy sessions in the child |
| Operation | Required when used |
|---|---|
mmap, mmap64 |
Translate backend offsets to shared memfd mappings |
munmap |
Release backend mapping ownership, when mappings are tracked |
mremap |
Reject or correctly update tracked mappings, when mappings are tracked |
v4l2_* entry points |
Cover applications that use libv4l rather than libc calls |
poll, ppoll, select, pselect, and epoll operate directly on the
synthetic descriptor's eventfd and are not interposed.
- Direct
syscallandio_uringsubmissions bypassLD_PRELOAD. - Secure execution may discard
LD_PRELOAD. - Automatic sysfs and udev discovery are separate compatibility layers.
- Dummy descriptors are close-on-exec and are not inherited across
exec. - Forked children discard inherited dummy-device sessions and may reopen them.
- Every successful open owns one backend-private session state object.
- Every descriptor alias references exactly one session.
- Duplicates share device state and file-status flags.
- Closing one alias does not stop a session while another alias remains.
- Closing the final alias releases backend state exactly once, after in-flight operations finish.
- Bulk close operations cannot leave stale registry entries.
- Operations on unrelated descriptors are forwarded without modification.
- Broker disconnect wakes blocked clients before operations begin returning a stable terminal error.
- A backend publishes one token only when one operation becomes consumable.
- Consuming that operation removes exactly one token.
- Dropped or replaced backend data does not create a token.
- Reset drains outstanding readiness.
- A terminal backend error is sticky and leaves the descriptor readable until the application closes it.
- Real files and descriptors remain unaffected.
- A registered probe path opens without a kernel device.
- Path and descriptor metadata report the configured character device.
poll,select, andepollblock and wake correctly.- All descriptor duplication paths share one session.
- The final close performs one teardown.
close_rangecannot leave stale registrations.- A forked child cannot corrupt its parent's session.
- Blocking and nonblocking operations return stable Linux errors.
- Concurrent opens create independent sessions.
- Broker disconnect wakes a blocked client and produces a terminal error.
The first implementation backend is /dev/fauxdev-probe. It only validates
this contract; it does not implement a camera or V4L2.
The /dev/video0 backend exercises the single-planar V4L2 MMAP sequence with
either a fixed RGB24 test pattern or broker-supplied frames. It currently
supports blocking and nonblocking dequeue, but frame pacing, device controls,
and formats beyond 64×48 RGB24 remain outside this backend. The Android
Camera2 broker is an opt-in companion, not part of the Linux preload library.
- Header and ancillary descriptor counts must agree.
- Descriptors pass in both directions with close-on-exec set.
- A sealed
memfdcan be mapped read-only with unchanged contents. - A backend error response leaves the connection usable.
- Peer disconnect wakes readiness and produces a stable
EPIPE.