+#endif // DARWIN_CLEANUP_CF
+
+#if DARWIN_CLEANUP_IOKIT
+/*!
+ * @define __os_iorelease
+ * An attribute that may be applied to a variable's type. This attribute causes
+ * the variable to be passed to IOObjectRelease() when it goes out of scope.
+ * Applying this attribute to a variable which does not reference a valid IOKit
+ * object will result in undefined behavior. If the variable's value is
+ * IO_OBJECT_NULL upon going out-of-scope, no cleanup is performed.
+ *
+ *
+ * In order to use, you must define the DARWIN_CLEANUP_IOKIT macro to 1 prior to
+ * including this header.
+ */
+#define __os_iorelease __attribute__((cleanup(__os_cleanup_iorelease)))
+static inline void
+__os_cleanup_iorelease(void *__p)
+{
+ kern_return_t kr = KERN_FAILURE;
+ io_object_t *iop = (io_object_t *)__p;
+ io_object_t io = *iop;
+
+ if (io == IO_OBJECT_NULL) {
+ return;
+ }
+
+ kr = IOObjectRelease(io);
+ if (kr) {
+ os_crash("IOObjectRetain: %{mach.errno}d", kr);
+ }
+}
+
+/*!
+ * @define __os_ioclose
+ * An attribute that may be applied to a variable's type. This attribute causes
+ * the variable to be passed to IOServiceClose() when it goes out of scope.
+ * Applying this attribute to a variable which does not reference a valid IOKit
+ * connection will result in undefined behavior. If the variable's value is
+ * IO_OBJECT_NULL upon going out-of-scope, no cleanup is performed.
+ *
+ * In order to use, you must define the DARWIN_CLEANUP_IOKIT macro to 1 prior to
+ * including this header.
+ */
+#define __os_ioclose __attribute__((cleanup(__os_cleanup_ioclose)))
+static inline void
+__os_cleanup_ioclose(void *__p)
+{
+ kern_return_t kr = KERN_FAILURE;
+ io_connect_t *iop = (io_object_t *)__p;
+ io_connect_t io = *iop;
+
+ if (io == IO_OBJECT_NULL) {
+ return;
+ }
+
+ kr = IOServiceClose(io);
+ if (kr) {
+ os_crash("IOObjectRelease: %{mach.errno}d", kr);
+ }
+}
+#endif // DARWIN_CLEANUP_IOKIT