As with optional hooks, this example consists of three files which can be found in .../modules/experimental: mod_optional_fn_export.c, mod_optional_fn_export.h and mod_optional_fn_import.c. (Note that comments for this example follow the code line(s) to which they refer.)
First the header, mod_optional_fn_export.h:
#include "apr_optional.h"
Get the optional function support from APR.
APR_DECLARE_OPTIONAL_FN(int,TestOptionalFn,(const char *));
And declare our optional function, which really looks like
int TestOptionalFn(const
char
*)
.
Now the exporting file, mod_optional_fn_export.c:
#include "httpd.h" #include "http_config.h" #include "http_log.h" #include "mod_optional_fn_export.h"
As always, we start with the headers, including our own.
static int TestOptionalFn(const char *szStr) { ap_log_error(APLOG_MARK,APLOG_ERR,OK,NULL, "Optional function test said: %s",szStr); return OK; }
This is the optional function — all it does is log the fact that it was called.
static void ExportRegisterHooks(apr_pool_t *p) { APR_REGISTER_OPTIONAL_FN(TestOptionalFn); }
During hook registration we register the optional function.
module optional_fn_export_module= { STANDARD20_MODULE_STUFF, NULL, NULL, NULL, NULL, NULL, ExportRegisterHooks };
And finally, we see the module structure containing just the hook registration function.
Now the module that uses the optional function, mod_optional_fn_import.c:
#include "httpd.h" #include "http_config.h" #include "mod_optional_fn_export.h" #include "http_protocol.h"
These are the headers. Of course, we have to include the header that declares the optional function.
static APR_OPTIONAL_FN_TYPE(TestOptionalFn) *pfn;
We declare a pointer to the optional function — note that the
macro APR_OPTIONAL_FN_TYPE
gets us the type of the
function from its name.
static int ImportLogTransaction(request_rec *r) { if(pfn) return pfn(r->the_request); return DECLINED; }
Further down we will hook the log_transaction
hook, and when it gets called we’ll then call the
optional function — but only if its present, of course!
static void ImportFnRetrieve(void) { pfn=APR_RETRIEVE_OPTIONAL_FN(TestOptionalFn); }
We retrieve the function here — this function is called by the
optional_fn_retrieve
hook (also registered later),
which happens at the earliest possible moment after hook
registration.
static void ImportRegisterHooks(apr_pool_t *p) { ap_hook_log_transaction(ImportLogTransaction,NULL,NULL,APR_HOOK_MIDDLE); ap_hook_optional_fn_retrieve(ImportFnRetrieve,NULL,NULL,APR_HOOK_MIDDLE); }
And here’s where we register our hooks.
module optional_fn_import_module = { STANDARD20_MODULE_STUFF, NULL, NULL, NULL, NULL, NULL, ImportRegisterHooks };
And, once more, the familiar module structure.