diff options
Diffstat (limited to 'libportseal/portseal.h')
-rw-r--r-- | libportseal/portseal.h | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/libportseal/portseal.h b/libportseal/portseal.h new file mode 100644 index 0000000..5ad06b0 --- /dev/null +++ b/libportseal/portseal.h @@ -0,0 +1,73 @@ +#ifndef __PORTSEAL__ +#define __PORTSEAL__ + +#define _GNU_SOURCE +#include <mach.h> +#include <stddef.h> + +extern int ports[]; + +void *portseal_malloc (size_t) __attribute__ ((malloc)); +void portseal_free (void *); + +mach_port_t portseal_set_port (mach_port_t *, mach_port_t); +void portseal_decrement (mach_port_t); +void portseal_decrement_p (mach_port_t*); +void portseal_increment (mach_port_t); + +#define PORTSEAL_CLEANUP(T, I, V) \ + __attribute__ ((cleanup (portseal_decrement_p))) T I = V +#define PORTSEAL_CLEANUP_I(T, I, V, E) \ + __attribute__ ((cleanup (portseal_decrement_p))) T I = V; \ + portseal_set_port (&I, E) + +#define PORTSEAL_WRAP(F, P) \ + ({ \ + mach_port_t *_p = (P); \ + mach_port_t _old = *_p; \ + (F); \ + mach_port_t _new = *_p; \ + if (_old != _new) \ + { \ + portseal_decrement (_old); \ + portseal_increment (_new); \ + } \ + }) + +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +/* Test for GCC >= 34.9 */ +#if GCC_VERSION >= 40900 +/* use __auto_type */ +#define PORTSEAL_WRAP_R(F, P) \ + ({ \ + mach_port_t *_p = (P); \ + mach_port_t _old = *_p; \ + __auto_type _result = (F); \ + mach_port_t _new = *_p; \ + if (_old != _new) \ + { \ + portseal_decrement (_old); \ + portseal_increment (_new); \ + } \ + _result; \ + }) +#else +#define PORTSEAL_WRAP_R(F, P) \ + ({ \ + mach_port_t *_p = (P); \ + mach_port_t _old = *_p; \ + typeof (F) _result = (F); \ + mach_port_t _new = *_p; \ + if (_old != _new) \ + { \ + portseal_decrement (_old); \ + portseal_increment (_new); \ + } \ + _result; \ + }) +#endif + +#endif /* __PORTSEAL__ */ |