S6-LIBFTRIG(7)
πΈ S6-LIBFTRIG(7) β the s6-libftrig of the manual-pages world β¨
okay so real talk: this is the s6-libftrig man page, from the Miscellaneous Information Manual section of your friendly neighbourhood Unix docs, and it's all about a portable Unix C programming interface that lets one process (we call it the subscriber, or listener) get instantly notified when another process (the notifier, or writer) signals an event. bestie, it's giving β¨ event-driven excellence β¨ and you're gonna love it π
π NAME π
s6-libftrig β a portable Unix C programming interface allowing a process (the subscriber or listener) to be instantly notified when another process (the notifier or writer) signals an event π
π¦ DESCRIPTION π¦
πΈ What is notification?
π Notification vs. polling
So picture this: process A is notified of an event E when it gets an instant lil' heads-up that event E has happened β and yes, that notice may absolutely disrupt A's execution flow, that's the whole point, main character energy fr fr.
Notification is the opposite of polling, where A has to periodically (every T milliseconds, like clockwork, exhausting) check whether E happened, and genuinely has no other way to be informed of it π
Polling is generally considered bad practice β and it's inferior to notification in practically every case β for three reasons:
- Reaction time. When event E happens, process A does not know it instantly. It will only learn of E, and be able to react to it, when it explicitly checks for E; and if E happened right after A performed the check, this can take as long as T milliseconds (the polling period). Polling processes have reaction delays due to the polling periods. π the lag is real.
- Resource consumption. Even if no event ever happens, process A will still wake up needlessly every T milliseconds. This might not seem like a problem, but it is a serious one in energy-critical environments. Polling processes use more CPU time than is necessary and are not energy-friendly. π₯ not the vibe in a battery-powered world.
- Conflict between the two above reasons. The longer the polling period, the more energy-friendly the process, but the longer the reaction time. The shorter the polling period, the shorter the reaction time, but the more resource-consuming the process. A delicate balance has to be found, and acceptable behaviour is different in every case, so there's no general rule of optimization. π it's giving "pick your poison".
Notification, on the other hand, is generally optimal: reaction time is zero, and resource consumption is minimal β a process can sleep as soon as it's not handling an event, and only wake up when needed. π literally the dream.
Of course, the problem of notification is that it's often more difficult to implement. Notification frameworks are generally more complex, involving lots of asynchronism; polling is widely used because it's easy<sup>[1]</sup>. π«Ά (yes the footnote is real, it's at the bottom, keep reading bestie)
π§ Notifications and Unix
Unix provides several frameworks so that a process B (or the kernel) can notify process A. let's do a lil' vibe check on each:
- Signals. The simplest Unix notification mechanism. Sending events amounts to a
kill(2)call, and receiving events amounts to installing a signal handler (preferably using a self-pipe<sup>[2]</sup> if mixing signals with an event loop). Unfortunately, Unix signals, even the more recent and powerful real-time POSIX signals, have important limitations when it's about generic notification:- Non-root processes can only send signals to a very restricted and implementation-dependent set of processes (roughly, processes with the same UID). This is a problem when designing secure programs that make use of Unix privilege separation. π¬
- You need to know the PID of a process to send it signals. This is generally impractical; process management systems that do not use supervisor processes have to do exactly that, and they resort to unreliable, ugly hacks (
.pidfiles) to track down process PIDs. π not the.pidfiles...
- BSD-style IPCs, i.e. file descriptors to perform
select(2)/poll(2)system calls on, in an asynchronous event loop. This mechanism is very widely used, and rightly so, because it's extremely generic and works in every ordinary situation; you have to be doing very specific stuff<sup>[3]</sup> to reach its limits. If process A is reading on fd f, it is notified every time another process makes f readable β for instance by writing a byte to the other end if f is the reading end of a pipe. And indeed, this is hows6-libftrigworks internally; buts6-libftrigis needed because direct use of BSD-style IPCs also has limitations:- Anonymous pipes are the simplest and most common BSD-style IPC. If there is a pipe from process B to process A, then B can notify A by writing to the pipe. The limitation is that A and B must have a common ancestor that created the pipe; two unrelated processes cannot communicate this way. π₯² so close yet so far.
- Sockets are a good many-to-one notification system: once a server is up, it can be notified by any client, and notify all its clients. The limitation of sockets is that the server must be up before the client, which prevents us from using them in a general notification scheme. π chicken-and-egg but make it Unix.
- System V IPCs, i.e. message queues and semaphores. The interfaces to those IPCs are quite specific and can't mix with select/poll loops, that's why nobody in their right mind uses them. π harsh but like... true.
π What we want
We need a general framework to:
- allow an event-generating process to broadcast notifications to every process that asked for one, without having to know their PIDs;
- allow a process to subscribe to a "notification channel" and be instantly, asynchronously notified when an event occurs on this channel. β¨
This requires a many-to-many approach that Unix does not provide natively, and that is what s6-libftrig does. slay.
That's what a bus is for. D-Bus already does all this. π
Yes, a bus is a good many-to-many notification mechanism indeed. However, a Unix bus can only be implemented via a daemon β you need a long-running process, i.e. a service, to implement a bus. And s6 is a supervision suite, i.e. a set of programs designed to manage services; we would like to be able to use notifications in the supervision suite, to be able to wait for a service to be up or down... without relying on a particular service to be up. s6-libftrig provides a notification mechanism that does not need a bus service to be up; that's its main advantage over a bus. π
If you are not concerned with supervision and can depend on a bus service, though, then yes, by all means, use a bus for your notification needs. There is a skabus<sup>[4]</sup> project in the making, which aims to be simpler, smaller and more maintainable than D-Bus. π«Ά we love options.
π How to use s6-libftrig
s6-libftrig is really a part of libs6: all the functions are implemented in the libs6.a archive, or the libs6.so dynamic shared object. However, the interfaces are different for notifiers and listeners β iykyk:
- Notifiers use the
s6-ftrigw(7)interface. βοΈ - Listeners use the
s6-ftrigr(7)interface. π
β SEE ALSO β
s6-accessrules(7), s6-fdholder(7), s6-ftrigr(7), s6-ftrigw(7), s6-libs6(7), s6-s6lock(7)
go read those next, bestie, they're iconic π
[1] https://despair.com/cdn/shop/products/mediocritylitho.png [2] https://skarnet.org/software/skalibs/libstddjb/selfpipe.html [3] http://www.kegel.com/c10k.html [4] https://skarnet.org/software/skabus/
This man page is ported from the authoritative documentation at: https://skarnet.org/software/s6/ftrig.html πΈ (so if you wanna fact-check me, that's where the receipts live)
π AUTHORS π
- Laurent Bercot
- Alexis <flexibeast@gmail.com> (man page port) π«Ά
mwah, that's the whole page π this Debian build of S6-LIBFTRIG(7) is dated June 30, 2025 β go be instantly notified about everything, you absolute icon πβ¨
π¦ where this page comes from
- nixpkgs unstable: s6 2.15.1.0
- nixpkgs unstable: s6-man-pages 2.14.0.1.4
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms