summaryrefslogtreecommitdiff
path: root/libportseal/portseal.h
diff options
context:
space:
mode:
Diffstat (limited to 'libportseal/portseal.h')
-rw-r--r--libportseal/portseal.h73
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__ */