79d9f32aec58f6bec85d1bed07ba329473363b72
[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 struct bitfield *alloc_bitfield(unsigned int maxbit);
86
87 void _log_bitfield_overflow(const char *f, unsigned int bit, unsigned int len);
88 #define log_bitfield_overflow(bit, len) \
89         _log_bitfield_overflow(__func__, bit, len)
90
91 static inline bool is_bit_set_in_bitfield(unsigned int bit,
92                                        const struct bitfield *bf)
93 {
94         if (bit >= bf->len) {
95                 log_bitfield_overflow(bit, bf->len);
96                 return false;
97         }
98         return !!(bf->bits[bit / bits_per_slot] &
99                   (1ULL << (bit % bits_per_slot)));
100 }
101
102 static inline void set_bit_in_bitfield(unsigned int bit, struct bitfield *bf)
103 {
104         if (bit >= bf->len) {
105                 log_bitfield_overflow(bit, bf->len);
106                 return;
107         }
108         bf->bits[bit / bits_per_slot] |= (1ULL << (bit % bits_per_slot));
109 }
110
111 static inline void clear_bit_in_bitfield(unsigned int bit, struct bitfield *bf)
112 {
113         if (bit >= bf->len) {
114                 log_bitfield_overflow(bit, bf->len);
115                 return;
116         }
117         bf->bits[bit / bits_per_slot] &= ~(1ULL << (bit % bits_per_slot));
118 }
119
120 #define steal_ptr(x)                   \
121         ({                             \
122                 void *___p = x;        \
123                 x = NULL;              \
124                 ___p;                  \
125         })
126
127 void cleanup_charp(char **p);
128 void cleanup_ucharp(unsigned char **p);
129 #endif /* _UTIL_H */