Annotation of coherent/f/usr/include/kernel/bufcall.h, revision 1.1.1.1

1.1       root        1: #ifndef        __KERNEL_BUFCALL_H__
                      2: #define        __KERNEL_BUFCALL_H__
                      3: 
                      4: /*
                      5:  * This header file contains a number of definitions aimed at working around
                      6:  * the enormous problems generated by the existence of callback functions
                      7:  * as implemented by bufcall (), ie without argument checking. See the
                      8:  * definition of the str_event structure in <sys/strmlib.h> for a more
                      9:  * complete discussion of the possible lossage caused by this.
                     10:  */
                     11: 
                     12: /*
                     13:  *-IMPORTS:
                     14:  *     <common/ccompat.h>
                     15:  *             __ANY_ARGS__
                     16:  *             __INLINE__
                     17:  *             __USE_INLINE__
                     18:  *             __PROTO ()
                     19:  *     <common/xdebug.h>
                     20:  *             __LOCAL__
                     21:  *     <sys/stream.h>
                     22:  *             queue_t
                     23:  *             toid_t
                     24:  *             uint_t
                     25:  */
                     26: 
                     27: #include <common/ccompat.h>
                     28: #include <common/xdebug.h>
                     29: #include <sys/stream.h>
                     30: 
                     31: 
                     32: /*
                     33:  * The most appealing solution to this problem is to define a solution that
                     34:  * works with inline functions to get full argument type checking, and then
                     35:  * to define an intermediate level for C that simply deals with ensuring that
                     36:  * the arguments are passed through the regular bufcall () mechanism without
                     37:  * lossage.
                     38:  *
                     39:  * Since the only genuinely safe way of doing this is via the use of stdargs
                     40:  * (which require that the function be declared that way, in ISO C it is
                     41:  * distinctly unsafe to cast function pointers such that the argument
                     42:  * definitions are different). Either an underlying implementation uses this
                     43:  * form of function call or there must be a forwarding function written that
                     44:  * does some form of similar hack to perform what is effectively an unsafe
                     45:  * cast.
                     46:  *
                     47:  * In order to make the job of declaring potential fully-type-safe versions
                     48:  * of the forwarding function, we provide a template-style macro that users
                     49:  * can try and use.
                     50:  */
                     51: 
                     52: /*
                     53:  * If you are using this header with an AT&T STREAMS implementation, either
                     54:  * you can directly call bufcall () (if the AT&T header is not in fact
                     55:  * prototyped) or you can must bufcall () indirectly through a special
                     56:  * function safe_bufcall (). If you are using the MWC-supplied STREAMS, then
                     57:  * bufcall () has been implemented and prototyped such that it does not
                     58:  * perform any type-checking of the callback or callback-argument arguments.
                     59:  *
                     60:  * If you are compiling with the AT&T implementation and have determined that
                     61:  * it is safe to do so, either define __STDARG_BUFCALL__ below or define it
                     62:  * in the compiler command line.
                     63:  */
                     64: 
                     65: /* #define __STDARG_BUFCALL__ */
                     66: 
                     67: /*
                     68:  * safe_bufcall () does a bufcall () but effectively overrides any declared
                     69:  * prototype for bufcall (). In certain cases the underlying bufcall ()
                     70:  * works this way.
                     71:  */
                     72: 
                     73: #ifdef __STDARG_BUFCALL__
                     74: 
                     75: # define       safe_bufcall(s,p,f,a)           bufcall (s, p, f, a)
                     76: # define       safe_esbbcall(p,f,a)            esbbcall (p, f, a)
                     77: 
                     78: #else
                     79: 
                     80: __EXTERN_C_BEGIN__
                     81: 
                     82: toid_t         safe_bufcall    __PROTO ((uint_t _size, int _pri, ...));
                     83: toid_t                 safe_esbbcall   __PROTO ((int _pri, ...));
                     84: 
                     85: __EXTERN_C_END__
                     86: 
                     87: #endif
                     88: 
                     89: 
                     90: /*
                     91:  * Clients should follow the general form here for declaring wrappers for
                     92:  * callbacks that are private to clients (in general, the following types
                     93:  * of callbacks are the only ones that would be visible at anything greater
                     94:  * than file scope).
                     95:  */
                     96: 
                     97: 
                     98: #if    __USE_INLINE__ && __USE_PROTO__
                     99: 
                    100: # define       __INLINE_BUFCALL(name,type)\
                    101:     __LOCAL__ __INLINE__ toid_t __CONCAT (bufcall_, name) \
                    102:                (uint_t _size, int _pri, void (* _func) (type), type _arg) { \
                    103:       return safe_bufcall (_size, _pri, _func, _arg); \
                    104:     }
                    105: # define       __INLINE_ESBBCALL(name,type)\
                    106:     __LOCAL__ __INLINE__ toid_t __CONCAT (esbbcall_ ,name) \
                    107:                (int _pri, void (* _func) (type), type _arg) { \
                    108:       return safe_esbbcall (_pri, _func, arg); \
                    109:     }
                    110: 
                    111: __LOCAL__ __INLINE__
                    112:   toid_t bufcall_void (uint_t _size, int _pri, void (* _func) (void)) {
                    113:        return safe_bufcall (_size, _pri, _func, 0);
                    114: }
                    115: 
                    116: __INLINE_BUFCALL (int, int);
                    117: __INLINE_BUFCALL (long, long);
                    118: __INLINE_BUFCALL (queue, queue_t *);
                    119: 
                    120: __LOCAL__ __INLINE__
                    121:   toid_t esbbcall_void (int _pri, void (* _func) (void)) {
                    122:        return safe_esbbcall (_pri, _func, 0);
                    123: }
                    124: 
                    125: __INLINE_ESBBCALL (int, int);
                    126: __INLINE_ESBBCALL (long, long);
                    127: __INLINE_ESBBCALL (queue, queue_t *);
                    128: 
                    129: #else  /* if ! __USE_INLINE__ || ! __PROTO__ */
                    130: 
                    131: # define       bufcall_void(s,p,f)             safe_bufcall (s, p, f, 0)
                    132: # define       bufcall_int(s,p,f,a)            safe_bufcall (s, p, f,\
                    133:                                                              (int) (a))
                    134: # define       bufcall_long(s,p,f,a)           safe_bufcall (s, p, f,\
                    135:                                                              (long) (a))
                    136: # define       bufcall_queue(s,p,f,a)          safe_bufcall (s, p, f,\
                    137:                                                              (queue_t *) (a))
                    138: 
                    139: # define       esbbcall_void(p,f)              safe_esbbcall (p, f, 0)
                    140: # define       esbbcall_int(p,f,a)             safe_esbbcall (p, f, (int) (a))
                    141: # define       esbbcall_long(p,f,a)            safe_esbbcall (p, f, (long) (a))
                    142: # define       esbbcall_queue(p,f,a)           safe_esbbcall (p, f, (queue_t *) (a))
                    143: 
                    144: #endif /* ! __USE_INLINE__ || ! __PROTO__ */
                    145: 
                    146: #endif /* ! defined (__KERNEL_BUFCALL_H__) */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.