FWIW, I don't think it would wind up being spelled with attribute syntax because we would likely want programmers to have a guarantee that the cleanup will happen (and attributes can be ignored by the implementation).
FWIW, I don't think it would wind up being spelled with attribute syntax because we would likely want programmers to have a guarantee that the cleanup will happen (and attributes can be ignored by the implementation).
#ifdef __STDC_CLEANUP__
#define my_cleanup(func) stdc_cleanup(func)
#else
#define my_cleanup(func) __attribute__((cleanup(func)))
#endif
i.e. it would require that it at least goes in the same places as an attribute.So I guess it needs someone to take that and update it, also to pull up a full list of current Linux software which is using this feature (which as I say these days is a surprising amount).
#define frr_with_privs(privs) \
for (struct zebra_privs_t *_once = NULL, \
*_privs __attribute__( \
(unused, cleanup(_zprivs_lower))) = \
_zprivs_raise(privs, __func__); \
_once == NULL; _once = (void *)1)
This gives us a block construct that guarantees elevated privileges are dropped when the block is done: frr_with_privs(privs) {
... whatever ...
break; /* exit block, drop privileges */
return; /* return, drop privileges */
}https://github.com/libguestfs/nbdkit/blob/e58d28d65bfea3af36...
You end up with code like this:
https://github.com/libguestfs/nbdkit/blob/e58d28d65bfea3af36...
It's so useful to be able to be sure the lock is released on all return paths. Also because it's scope-level you can scope your locks tightly to where they are needed.