diff --git a/src/basic/umask-util.h b/src/basic/umask-util.h index e964292eaf4..cad745170eb 100644 --- a/src/basic/umask-util.h +++ b/src/basic/umask-util.h @@ -8,21 +8,19 @@ #include "macro.h" static inline void umaskp(mode_t *u) { - umask(*u); + umask(*u & 0777); } #define _cleanup_umask_ _cleanup_(umaskp) -struct _umask_struct_ { - mode_t mask; - bool quit; -}; +/* We make use of the fact here that the umask() concept is using only the lower 9 bits of mode_t, although + * mode_t has space for the file type in the bits further up. We simply OR in the file type mask S_IFMT to + * distinguish the first and the second iteration of the RUN_WITH_UMASK() loop, so that we can run the first + * one, and exit on the second. */ -static inline void _reset_umask_(struct _umask_struct_ *s) { - umask(s->mask); -}; +assert_cc((S_IFMT & 0777) == 0); #define RUN_WITH_UMASK(mask) \ - for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \ - !_saved_umask_.quit ; \ - _saved_umask_.quit = true) + for (_cleanup_umask_ mode_t _saved_umask_ = umask(mask) | S_IFMT; \ + FLAGS_SET(_saved_umask_, S_IFMT); \ + _saved_umask_ &= 0777)