FTS * fts_open_b(char * const *argv, int options, fts_block_t compar) { FTS *sp; struct _fts_private *priv; /* Check arguments. */ if ((errno = _fts_open_argcheck(argv, options)) != 0) return (NULL); /* Check to make sure we have the block runtime. */ if (_Block_copy == 0) { errno = ENOSYS; return (NULL); } /* Allocate/initialize the stream. */ if ((priv = calloc(1, sizeof(*priv))) == NULL) return (NULL); sp = &priv->ftsp_fts; sp->fts_compar_b = _Block_copy(compar); sp->fts_options = options | FTS_COMPAR_B; return (_fts_open_common(argv, priv)); }
/** * Register a block to be performed at exit. */ int atexit_b(atexit_block func) { struct atexit_fn fn; int error; if (_Block_copy == 0) { errno = ENOSYS; return -1; } func = _Block_copy(func); // Blocks are not C++ destructors, but they have the same signature (a // single void* parameter), so we can pretend that they are. fn.fn_type = ATEXIT_FN_CXA; fn.fn_ptr.cxa_func = (void(*)(void*))GET_BLOCK_FUNCTION(func); fn.fn_arg = func; fn.fn_dso = NULL; error = atexit_register(&fn); return (error); }
static const void * BlockRetainCallback(CFAllocatorRef allocator, const void *value) { return (const void *) _Block_copy((void *) value); }