File: util.h

package info (click to toggle)
multipath-tools 0.14.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,088 kB
  • sloc: ansic: 64,885; perl: 1,622; makefile: 742; sh: 732; pascal: 155
file content (163 lines) | stat: -rw-r--r-- 4,752 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#ifndef UTIL_H_INCLUDED
#define UTIL_H_INCLUDED

#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
/* for rlim_t */
#include <sys/resource.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>

#ifndef __GLIBC_PREREQ
#define __GLIBC_PREREQ(x, y) 0
#endif

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

struct udev_device;
size_t strchop(char *);

const char *libmp_basename(const char *filename);
#ifndef __GLIBC__
#define basename(x) libmp_basename(x)
#endif
int basenamecpy (const char *src, char *dst, size_t size);
int filepresent (const char *run);
char *get_next_string(char **temp, const char *split_char);
int get_word (const char * sentence, char ** word);
size_t libmp_strlcpy(char * restrict dst, const char * restrict src, size_t size);
size_t libmp_strlcat(char * restrict dst, const char * restrict src, size_t size);
#if defined(__GLIBC__) && ! (__GLIBC_PREREQ(2, 38))
#define strlcpy(dst, src, size) libmp_strlcpy(dst, src, size)
#define strlcat(dst, src, size) libmp_strlcat(dst, src, size)
#endif
dev_t parse_devt(const char *dev_t);
char *convert_dev(char *dev, int is_path_device);
void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached);
int get_linux_version_code(void);
int safe_write(int fd, const void *buf, size_t count);
void set_max_fds(rlim_t max_fds);
int should_exit(void);

#define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc))
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))

#define safe_sprintf(var, format, args...)	\
	safe_snprintf(var, sizeof(var), format, ##args)

#define safe_snprintf(var, size, format, args...)      \
	({								\
		size_t __size = size;					\
		int __ret;						\
									\
		__ret = snprintf(var, __size, format, ##args);		\
		__ret < 0 || (size_t)__ret >= __size;			\
	})

#define pthread_cleanup_push_cast(f, arg)		\
	pthread_cleanup_push(((void (*)(void *))&f), (arg))

void cleanup_fd_ptr(void *arg);
void cleanup_free_ptr(void *arg);
void cleanup_mutex(void *arg);
void cleanup_vector_free(void *arg);
void cleanup_fclose(void *p);

struct scandir_result {
	struct dirent **di;
	int n;
};
void free_scandir_result(struct scandir_result *);

/*
 * ffsll() is also available on glibc < 2.27 if _GNU_SOURCE is defined.
 * But relying on that would require that every program using this header file
 * set _GNU_SOURCE during compilation, because otherwise the library and the
 * program would use different types for bitfield_t, causing errors.
 * That's too error prone, so if in doubt, use ffs().
 */
#if __GLIBC_PREREQ(2, 27)
typedef unsigned long long int bitfield_t;
#define _ffs(x) ffsll(x)
#else
typedef unsigned int bitfield_t;
#define _ffs(x) ffs(x)
#endif
#define bits_per_slot (sizeof(bitfield_t) * CHAR_BIT)

union bitfield {
	struct {
		unsigned int len;
		bitfield_t bits[];
	};
	/* for initialization in the BITFIELD macro */
	struct {
		unsigned int __len;
		bitfield_t __bits[1];
	};
};

/*
 * BITFIELD: define a static bitfield of length bits_per_slot
 * (aka 64 on 64-bit architectures).
 * gcc 4.9.2 (Debian Jessie) raises an error if the initializer for
 * .__len comes first. Thus put .__bits first.
 * Use e.g. BUILD_BUG_ON() to make sure the bitfield size is sufficient
 * to hold the number of bits required.
 */
#define BITFIELD(name)							\
	union bitfield __storage_for__ ## name = {			\
		.__bits = { 0 },					\
		.__len = (bits_per_slot),				\
	}; \
	union bitfield *name = & __storage_for__ ## name

union bitfield *alloc_bitfield(unsigned int maxbit);

void log_bitfield_overflow__(const char *f, unsigned int bit, unsigned int len);
#define log_bitfield_overflow(bit, len) \
	log_bitfield_overflow__(__func__, bit, len)

static inline bool is_bit_set_in_bitfield(unsigned int bit, const union bitfield *bf)
{
	if (bit >= bf->len) {
		log_bitfield_overflow(bit, bf->len);
		return false;
	}
	return !!(bf->bits[bit / bits_per_slot] &
		  (1ULL << (bit % bits_per_slot)));
}

static inline void set_bit_in_bitfield(unsigned int bit, union bitfield *bf)
{
	if (bit >= bf->len) {
		log_bitfield_overflow(bit, bf->len);
		return;
	}
	bf->bits[bit / bits_per_slot] |= (1ULL << (bit % bits_per_slot));
}

static inline void clear_bit_in_bitfield(unsigned int bit, union bitfield *bf)
{
	if (bit >= bf->len) {
		log_bitfield_overflow(bit, bf->len);
		return;
	}
	bf->bits[bit / bits_per_slot] &= ~(1ULL << (bit % bits_per_slot));
}

#define steal_ptr(x)		       \
	({			       \
		void *___p = x;	       \
		x = NULL;	       \
		___p;		       \
	})

void cleanup_charp(char **p);
void cleanup_ucharp(unsigned char **p);
void cleanup_udev_device(struct udev_device **udd);
void cleanup_bitfield(union bitfield **p);
#endif /* UTIL_H_INCLUDED */