#ifndef fooutilshfoo #define fooutilshfoo #include #include #include #include #include struct list_head { struct list_head *next; struct list_head *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) static inline void list_init(struct list_head *list) { list->next = list; list->prev = list; } static inline void list_del(struct list_head *list) { list->next->prev = list->prev; list->prev->next = list->next; } static inline void list_add(struct list_head *new, struct list_head *list) { list->next->prev = new; new->next = list->next; new->prev = list; list->next = new; } static inline void list_replace(struct list_head *old, struct list_head *new) { old->prev->next = new; old->next->prev = new; new->next = old->next; new->prev = old->prev; old->next = old->prev = NULL; } static inline bool list_empty(struct list_head *list) { return list->next == list; } #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) #define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ &pos->member != (head); \ pos = list_next_entry(pos, member)) #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) static inline void* zmalloc(size_t size) { return calloc(1, size); } #define _cleanup_(x) __attribute__((cleanup(x))) #define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ static inline void func##p(type *p) { \ if (*p) \ func(*p); \ } \ struct __useless_struct_to_allow_trailing_semicolon__ static inline unsigned strv_length(char **strv) { unsigned len; for (len = 0; strv && *strv; strv++) len++; return len; } static inline void strv_free(char **l) { char **k; if (l) { for (k = l; *k; k++) free(k); free(l); } } DEFINE_TRIVIAL_CLEANUP_FUNC(char **, strv_free); #define _cleanup_strv_free_ _cleanup_(strv_freep) static inline void freep(void *p) { free(*(void**) p); } #define _cleanup_free_ _cleanup_(freep) DEFINE_TRIVIAL_CLEANUP_FUNC(int, close); #define _cleanup_close_ _cleanup_(closep) DEFINE_TRIVIAL_CLEANUP_FUNC(FILE *, fclose); #define _cleanup_fclose_ _cleanup_(fclosep) DEFINE_TRIVIAL_CLEANUP_FUNC(DIR *, closedir); #define _cleanup_closedir_ _cleanup_(closedirp) #define _cleanup_bus_flush_close_unref_ _cleanup_(sd_bus_flush_close_unrefp) #define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp) #define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp) #define _cleanup_event_source_unref_ _cleanup_(sd_event_source_unrefp) #endif