Imported Upstream version 0.8.9
[platform/upstream/multipath-tools.git] / libmultipath / util.h
1 #ifndef _UTIL_H
2 #define _UTIL_H
3
4 #include <stdlib.h>
5 #include <string.h>
6 #include <limits.h>
7 #include <sys/types.h>
8 /* for rlim_t */
9 #include <sys/resource.h>
10 #include <inttypes.h>
11 #include <stdbool.h>
12 #include <stdio.h>
13
14 size_t strchop(char *);
15 int basenamecpy (const char *src, char *dst, size_t size);
16 int filepresent (const char *run);
17 char *get_next_string(char **temp, const char *split_char);
18 int get_word (const char * sentence, char ** word);
19 size_t strlcpy(char * restrict dst, const char * restrict src, size_t size);
20 size_t strlcat(char * restrict dst, const char * restrict src, size_t size);
21 int devt2devname (char *, int, const char *);
22 dev_t parse_devt(const char *dev_t);
23 char *convert_dev(char *dev, int is_path_device);
24 void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached);
25 int systemd_service_enabled(const char *dev);
26 int get_linux_version_code(void);
27 int parse_prkey(const char *ptr, uint64_t *prkey);
28 int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags);
29 int safe_write(int fd, const void *buf, size_t count);
30 void set_max_fds(rlim_t max_fds);
31 int should_exit(void);
32
33 #define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc))
34 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
35
36 #define safe_sprintf(var, format, args...)      \
37         safe_snprintf(var, sizeof(var), format, ##args)
38
39 #define safe_snprintf(var, size, format, args...)      \
40         ({                                                              \
41                 size_t __size = size;                                   \
42                 int __ret;                                              \
43                                                                         \
44                 __ret = snprintf(var, __size, format, ##args);          \
45                 __ret < 0 || (size_t)__ret >= __size;                   \
46         })
47
48 #define pthread_cleanup_push_cast(f, arg)               \
49         pthread_cleanup_push(((void (*)(void *))&f), (arg))
50
51 void close_fd(void *arg);
52 void cleanup_free_ptr(void *arg);
53 void cleanup_mutex(void *arg);
54
55 struct scandir_result {
56         struct dirent **di;
57         int n;
58 };
59 void free_scandir_result(struct scandir_result *);
60
61 #ifndef __GLIBC_PREREQ
62 #define __GLIBC_PREREQ(x, y) 0
63 #endif
64 /*
65  * ffsll() is also available on glibc < 2.27 if _GNU_SOURCE is defined.
66  * But relying on that would require that every program using this header file
67  * set _GNU_SOURCE during compilation, because otherwise the library and the
68  * program would use different types for bitfield_t, causing errors.
69  * That's too error prone, so if in doubt, use ffs().
70  */
71 #if __GLIBC_PREREQ(2, 27)
72 typedef unsigned long long int bitfield_t;
73 #define _ffs(x) ffsll(x)
74 #else
75 typedef unsigned int bitfield_t;
76 #define _ffs(x) ffs(x)
77 #endif
78 #define bits_per_slot (sizeof(bitfield_t) * CHAR_BIT)
79
80 struct bitfield {
81         unsigned int len;
82         bitfield_t bits[];
83 };
84
85 #define STATIC_BITFIELD(name, length)                                   \
86         static struct {                                                 \
87                 unsigned int len;                                       \
88                 bitfield_t bits[((length) - 1) / bits_per_slot + 1];    \
89         } __static__ ## name = {                                        \
90                 .len = (length),                                        \
91                 .bits = { 0, },                                         \
92         }; \
93         struct bitfield *name = (struct bitfield *)& __static__ ## name
94
95 struct bitfield *alloc_bitfield(unsigned int maxbit);
96
97 void _log_bitfield_overflow(const char *f, unsigned int bit, unsigned int len);
98 #define log_bitfield_overflow(bit, len) \
99         _log_bitfield_overflow(__func__, bit, len)
100
101 static inline bool is_bit_set_in_bitfield(unsigned int bit,
102                                        const struct bitfield *bf)
103 {
104         if (bit >= bf->len) {
105                 log_bitfield_overflow(bit, bf->len);
106                 return false;
107         }
108         return !!(bf->bits[bit / bits_per_slot] &
109                   (1ULL << (bit % bits_per_slot)));
110 }
111
112 static inline void set_bit_in_bitfield(unsigned int bit, struct bitfield *bf)
113 {
114         if (bit >= bf->len) {
115                 log_bitfield_overflow(bit, bf->len);
116                 return;
117         }
118         bf->bits[bit / bits_per_slot] |= (1ULL << (bit % bits_per_slot));
119 }
120
121 static inline void clear_bit_in_bitfield(unsigned int bit, struct bitfield *bf)
122 {
123         if (bit >= bf->len) {
124                 log_bitfield_overflow(bit, bf->len);
125                 return;
126         }
127         bf->bits[bit / bits_per_slot] &= ~(1ULL << (bit % bits_per_slot));
128 }
129
130 #define steal_ptr(x)                   \
131         ({                             \
132                 void *___p = x;        \
133                 x = NULL;              \
134                 ___p;                  \
135         })
136
137 void cleanup_charp(char **p);
138 void cleanup_ucharp(unsigned char **p);
139 #endif /* _UTIL_H */