⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ap_hook.h

📁 mod_ssl-2.8.31-1.3.41.tar.gz 好用的ssl工具
💻 H
📖 第 1 页 / 共 2 页
字号:
#define FALSE 0#define TRUE  !FALSE#endif/* * Wrapper macros for the callback-function register/unregister calls.   *  * Background: Strict ANSI C doesn't allow a function pointer to be treated as * a void pointer on argument passing, but we cannot declare the argument as a * function prototype, because the functions can have arbitrary signatures. So * we have to use a void pointer here. But to not require explicit casts on * function pointers for every register/unregister call, we smooth the API a * little bit by providing these macros. */#define ap_hook_register(hook,func,ctx) ap_hook_register_I(hook,(void *)(func),ctx)#define ap_hook_unregister(hook,func)   ap_hook_unregister_I(hook,(void *)(func))/* * Prototypes for the hook API functions */API_EXPORT(void)          ap_hook_init         (void);API_EXPORT(void)          ap_hook_kill         (void);API_EXPORT(int)           ap_hook_configure    (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);API_EXPORT(int)           ap_hook_register_I   (char *hook, void *func, void *ctx);API_EXPORT(int)           ap_hook_unregister_I (char *hook, void *func);API_EXPORT(ap_hook_state) ap_hook_status       (char *hook);API_EXPORT(int)           ap_hook_use          (char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...);API_EXPORT(int)           ap_hook_call         (char *hook, ...);#endif /* AP_HOOK_H */#endif /* EAPI *//*=pod####  Embedded POD document##=head1 NAMEB<ap_hook> - B<Generic Hook Interface for Apache>=head1 SYNOPSISB<Hook Library Setup:> void ap_hook_init(void); void ap_hook_kill(void);B<Hook Configuration and Registration:> int ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode mode); int ap_hook_register(char *hook, void *func, void *ctx); int ap_hook_unregister(char *hook, void *func);B<Hook Usage:> ap_hook_state ap_hook_status(char *hook); int ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode mode, ...); int ap_hook_call(char *hook, ...);B<Hook Signature Constructors> (ap_hook_sig): AP_HOOK_SIG1(rc) AP_HOOK_SIG2(rc,a1) AP_HOOK_SIG3(rc,a1,a2) AP_HOOK_SIG4(rc,a1,a2,a3) AP_HOOK_SIG5(rc,a1,a2,a3,a4) AP_HOOK_SIG6(rc,a1,a2,a3,a4,a5) AP_HOOK_SIG7(rc,a1,a2,a3,a4,a5,a6) AP_HOOK_SIG8(rc,a1,a2,a3,a4,a5,a6,a7)B<Hook Modes Constructors> (ap_hook_mode): AP_HOOK_TOPMOST AP_HOOK_DECLINE(value) AP_HOOK_DECLTMP(value) AP_HOOK_ALLB<Hook States> (ap_hook_state): AP_HOOK_STATE_UNDEF AP_HOOK_STATE_NOTEXISTANT AP_HOOK_STATE_ESTABLISHED AP_HOOK_STATE_CONFIGURED  AP_HOOK_STATE_REGISTERED=head1 DESCRIPTIONThis library implements a generic hook interface for Apache which can be usedto loosely couple code through arbitrary hooks. There are two use cases forthis mechanism:=over 3=item B<1. Extension and Overrides>Inside a specific code section you want to perform a specific function callfor extension reasons.  But you want to allow one or more modules to implementthis function by registering hooks. Those hooks are registered on a stack andcan be even configured to have a I<decline> return value. As long as there arefunctions which return the decline value the next function on the stack istried. When the first function doesn't return the decline value the hook callstops. The original intent of this use case is to provide a flexible extensionmechanism where modules can override functionality.=item B<2. Intercommunication>Inside a specific code you have a function you want to export. But you firstwant to allow other code to override this function.  And second you want toexport this function without real object file symbol references. Instead youwant to register the function and let the users call this function by name. The original intent of this use case is to allow inter-module communicationwithout direct symbol references, which are a big I<no-no> for the I<DynamicShared Object> (DSO) situation.=backAnd the following design goals existed:=over 3=item B<1. Minimum code changes>The hook calls should look very similar to the corresponding direct functioncall to allow one to easily translate it. And the total amount of changes forthe hook registration, hook configuration and hook usage should be as small aspossible to minimize the total code changes. Additionally a shorthand APIfunction (ap_hook_use) should be provided which lets one trivially add a hookby just changing the code at a single location.=item B<2. The hook call has to be maximum flexible>In order to avoid nasty hacks, maximum flexiblity for the hook calls isneeded, i.e. any function signature (the set of types for the return value andthe arguments) should be supported.  And it should be possible toregister always a context (ctx) variable with a function which is passed tothe corresponding function when the hook call is performed.=backThe implementation of this library directly followed these two design goals.=head1 USAGEUsing this hook API is a four-step process:=over 3=item B<1. Initialization>Initialize or destroy the hook mechanism inside your application program: ap_hook_init();    : ap_hook_kill();=item B<2. Configuration>Configure a particular hook by specifing its name, signature and return typesemantic: ap_hook_configure("lookup", AP_HOOK_SIG2(ptr,ptr,ctx), AP_HOOK_DECLINE(NULL)); ap_hook_configure("setup", AP_HOOK_SIG2(int,ptr,char), AP_HOOK_DECLTMP(FALSE)); ap_hook_configure("read", AP_HOOK_SIG2(void,ptr), AP_HOOK_TOPMOST); ap_hook_configure("logit", AP_HOOK_SIG2(void,ptr), AP_HOOK_ALL);This configures four hooks: A hook named C<lookup> with the signature C<void *lookup(void *, void *)>(where the second argument is C<NULL> or the private context pointer of thehook function which can be optionally provided at the registration steplater) and a return code semantic which says: Proceed as long as theregistered lookup functions return C<NULL> or no more registered functionsexists. A call for this hook has to provide 2 argument only (a pointer to thereturn variable and the first argument), because the context isimplicitly provided by the hook mechanism. Sample idea: I<The first functionwho was successful in looking up a variable provides the value>.A hook named C<setup> with the signature C<int setup(void *, char)" and areturn code semantic equal to the one of the C<lookup> hook. But the declinereturn value is implemented by a temporay variable of the hook mechanism andonly used for the decline decision. So a call to this hook has to provide 2arguments only (the first and second argument, but no address to a returnvalue). Sample idea: I<Any function can handle the setup and when onefunction handled it stops the processing by indicating this with the returnvalue>.A hook named C<read> with the signature C<void read(void *)> and a return codesemantic which says: Only the top most function on the registered functionstack is tried (and independet of a possible return value in non-voidcontext). A call to this hook has to provide exactly 1 argument (thesingle argument to the hook function). Sample idea: I<We want touse a read function and allow others to override it, but independent how muchregistered functions exists, only top most (= last registered) functionoverrides and is used>.A hook named C<logit> with the signature C<void logit(void *)> and a returncode semantic which says: All registered functions on the hook functioin stackare tried. Sample idea: I<We pass a FILE pointer to the logging functions andany function can log whatever it wants>.=item B<3. Registration>Register the actual functions which should be used by the hook: ap_hook_register("lookup", mylookup, mycontext); ap_hook_register("setup", mysetup); ap_hook_register("read", myread); ap_hook_register("logit", mylogit);This registers the function C<mylookup()> under the C<lookup> hook with theprivate context given by the variable C<mycontext>. And it registers thefunction C<mysetup()> under the C<setup> hook without any context. Same forC<myread> and C<mylogit>.=item B<4. Usage>Finally use the hooks, i.e. instead of using direct function calls like         rc = mylookup(a1, a2); rc = mysetup(a1, a2); myread(a1); mylogit(a1);you now use: ap_hook_call("lookup", &rc, a1, a2); ap_hook_call("setup", &rc, a1, a2); ap_hook_call("read", a1); ap_hook_call("logit", a1);which are internally translated to: rc = mylookup(a1, a2, mycontext); rc = mysetup(a1, a2); myread(a1); mylogit(a1);Notice two things here: First the context (C<mycontext>) for the C<mylookup()>function is automatically added by the hook mechanism. And it is a different(and not fixed) context for each registered function, of course.  Second,return values always have to be pushed into variables and a pointer to themhas to be given as the second argument to C<ap_hook_call> (except forfunctions which have a void return type, of course).BTW, the return value of C<ap_hook_call()> is always C<TRUE> or C<FALSE>.C<TRUE> when at least one function call was successful (always the case forC<AP_HOOK_TOPMOST> and C<AP_HOOK_ALL>). C<FALSE> when all functionsreturned the decline value or no functions are registered at all.=back=head1 RESTRICTIONSTo make the hook implementation efficient and to not bloat up the code toomuch a few restrictions have to make:=over 3=item 1.Only function calls with up to 4 arguments are implemented. When more areneeded you can either extend the hook implementation by using more bits forthe signature configuration or you can do a workaround when the function isyour own one: Put the remaining (N-4-1) arguments into a structure and passonly a pointer (one argument) as the forth argument.=item 2.Only the following ANSI C variable types are supported: - For the return value:    void (= none), char, int, float, double, ptr (= void *) - For the arguments:   ctx  (= context), char, int, float, double, ptr (= void *)This means in theory that 6^5 (=7776) signature combinations are possible. Butbecause we don't need all of them inside Apache and it would bloat up the codetoo dramatically we implement only a subset of those combinations. Theimplemented signatures can be specified inside C<ap_hook.c> and thecorresponding code can be automatically generated by running ``C<perlap_hook.c>'' (yeah, no joke ;-).  So when you need a hook with a differentstill not implemented signature you either have to again use a workaround asabove (i.e. use a structure) or just add the signature to the C<ap_hook.c>file.=head1 EXAMPLEWe want to call `C<ssize_t read(int, void *, size_t)>' through hooks in orderto allow modules to override this call.  So, somewhere we have a replacementfunction for C<read()> defined (same signature, of course): ssize_t my_read(int, void *, size_t);We now configure a C<read> hook. Here the C<AP_HOOK_SIGx()> macro defines thesignature of the C<read()>-like callback functions and has to match theprototype of C<read()>. But we have to replace typedefs with the physicalunderlaying ANSI C types. And C<AP_HOOK_DECLINE()> sets the return value ofthe read()-like functions which forces the next hook to be called (here -1).And we register the original C<read()> function as the default hook. ap_hook_configure("read",                    AP_HOOK_SIG4(int,int,ptr,int),                    AP_HOOK_DECLINE(-1)); ap_hook_register("read", read);Now a module wants to override the C<read()> call and registers theC<my_read()> function: ap_hook_register("read", my_read);The function logically gets pushed onto a stack, so the execution order is thereverse registering order, i.e. I<last registered - first called>. Now we canreplace the standard C<read()> call bytes = read(fd, buf, bufsize); if (bytes == -1)    ...error...with the hook based call:  rc = ap_hook_call("read", &bytes, fd, buf, bufsize);  if (rc == FALSE)     ...error...Now internally the following is done: The call `C<bytes = my_read(fd, buf,bufsize)>' is done. When it returns not -1 (the decline value) nothingmore is done. But when C<my_read()> returns -1 the next function is tried:`C<bytes = read(fd, buf, bufsize)>'. When this one also returns -1 you get`rc == FALSE'. When it finally returns not -1 you get `rc == TRUE'.=head1 SEE ALSOap_ctx(3)=head1 HISTORYThe ap_hook(3) interface was originally designed and implemented in October 1998 by Ralf S. Engelschall.=head1 AUTHOR Ralf S. Engelschall rse@engelschall.com www.engelschall.com=cut*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -