AUPLUGIN(3)
π AUPLUGIN π
okay bestie, so this is the Linux Audit API plugin-helpers situation β it's the auplugin family from the auplugin(3) manual, and it's literally the whole "make ur plugin actually process audit events" toolkit. β¨ four functions, one header, and a whole lotta queue energy. let's get into it π«Ά
β¨ NAME β¨
auplugin_init, auplugin_stop, auplugin_event_loop, auplugin_event_feed β the plugin event processing helpers. that's the whole squad. π
πΈ SYNOPSIS πΈ
#include <auplugin.h>
int auplugin_init(int inbound_fd, unsigned queue_size, int q_flags,
const char *path);
void auplugin_stop(void);
void auplugin_event_loop(auplugin_callback_ptr callback);
int auplugin_event_feed(auparse_callback_ptr callback, unsigned
timer_interval, auplugin_timer_callback_ptr timer_cb);
π DESCRIPTION π
π
auplugin_init
so auplugin_init sets up the whole plugin framework, like the main character arriving at the function. the inbound_fd param is the file descriptor that's gonna hand you audit messages β typically standard input, iykyk. the queue_size argument controls the max number of events that can be queued up for processing (yes bestie, there's a limit, the queue is not infinite).
the q_flags parameter picks in-memory or file-backed storage, using the AUPLUGIN_Q_* constants that live in auplugin.h. if q_flags includes AUPLUGIN_Q_IN_FILE, then path is what specifies the backing file. and here's the cute part: any events already sitting in that file get queued on startup, so plugins resume processing the previously unhandled records. it's giving "we don't leave leftovers." π
the library keeps global state for its queue and worker threads. and this is important β only one plugin instance is supported, so callers must NOT invoke auplugin_init() concurrently from multiple threads. no cap. it returns 0 on success or -1 if initialization fails.
π auplugin_stop
auplugin_stop signals the framework to terminate. it's normally called from a SIGTERM handler or other shutdown logic β basically the "ok we're done here" button. π
π auplugin_event_loop
auplugin_event_loop starts a worker thread that delivers queued events to the callback function you hand it, one record at a time. the way this function blocks in the caller until auplugin_stop is invoked? iconic. it just sits there. patiently. like a bestie waiting for u to finish getting ready. π
π auplugin_event_feed
auplugin_event_feed behaves like auplugin_event_loop, except the queued events get fed to libauparse. the callback you provide must match the auparse_callback_ptr type.
the timer_interval argument says how many seconds the worker thread will wait for new records. a value of 0 disables the timer logic entirely (no timer, no stress β¨). when the interval elapses, auparse_feed_age_events gets called to flush the aged events. if timer_cb is not NULL, it gets invoked with the interval before the flush. passing a timer_cb of NULL keeps the default behaviour of calling auparse_feed_age_events only. the function returns 0 on success or -1 if libauparse couldn't be initialized.
π queue stats, because we love data
plugins can query queue statistics with auplugin_queue_depth, auplugin_queue_max_depth, and auplugin_queue_overflow. register a callback with auplugin_register_stats_callback, and then invoke it using auplugin_report_stats. obsessed with a plugin that knows its own queue numbers fr fr.
π¨ SIGNAL HANDLING π¨
ok so this part matters, bestie. plugins should establish signal handlers with sigaction(2) before entering the event loop. the SIGTERM handler should call auplugin_stop() to shut down the worker thread. handlers for other signals, like SIGHUP or SIGUSR1, should set global flags that get processed in the event or timer callbacks.
example:
static volatile sig_atomic_t reload;
static void handler(int sig)
{
if (sig == SIGTERM)
auplugin_stop();
else if (sig == SIGHUP)
reload = 1;
}
π lowkey do not skip the sigaction(2) step, it's not a vibe to raw-dog signal handling.
π SEE ALSO π
π AUTHOR π
Steve Grubb β the legend, the blueprint, the moment. π«Ά
and that's the whole page, babes π¦ this one came from Red Hat and it's dated June 2025 β so it's fresh, it's current, and it ate. mwah π β¨
π¦ where this page comes from
- alpine 3.23: audit-doc 4.1.2-r2 Β· LGPL-2.1-or-later
- alpine 3.24: audit-doc 4.1.2-r6 Β· LGPL-2.1-or-later
- arch rolling: audit 4.2.1-1 Β· GPL-2.0-or-later AND LGPL-2.0-or-later
- centos-stream 10: audit-libs-devel 4.2.1-3.el10 Β· LGPL-2.0-or-later
- fedora 43: audit-libs-devel 4.1.1-2.fc43 Β· LGPL-2.0-or-later
- fedora 43: audit-libs-devel 4.1.1-2.fc43 Β· LGPL-2.0-or-later
- fedora 43: audit-libs-devel 4.2.1-1.fc43 Β· LGPL-2.0-or-later
- fedora 43: audit-libs-devel 4.2.1-1.fc43 Β· LGPL-2.0-or-later
- fedora 44: audit-libs-devel 4.1.4-1.fc44 Β· LGPL-2.0-or-later
- fedora 44: audit-libs-devel 4.1.4-1.fc44 Β· LGPL-2.0-or-later
- fedora 44: audit-libs-devel 4.2.1-1.fc44 Β· LGPL-2.0-or-later
- fedora 44: audit-libs-devel 4.2.1-1.fc44 Β· LGPL-2.0-or-later
- nixpkgs unstable: audit 4.2.1
- ubuntu resolute: libauplugin-dev 1:4.1.2-1build1 Β· GPL-2.0-only
- ubuntu resolute: libauplugin-dev 1:4.1.2-1ubuntu0.1 Β· GPL-2.0-only
- ubuntu stonking: libauplugin-dev 1:4.1.2-1ubuntu1 Β· GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms