Line data Source code
1 : /*
2 : * Copyright (c) Artem Bityutskiy, 2007, 2008
3 : *
4 : * This program is free software; you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation; either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 : * the GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program; if not, write to the Free Software
16 : * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 : */
18 :
19 : #ifndef __MTD_UTILS_COMMON_H__
20 : #define __MTD_UTILS_COMMON_H__
21 :
22 : #include <stdbool.h>
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <ctype.h>
26 : #include <string.h>
27 : #include <fcntl.h>
28 : #include <errno.h>
29 : #include <features.h>
30 : #include <inttypes.h>
31 : #include <unistd.h>
32 : #include <sys/sysmacros.h>
33 :
34 : #ifndef PROGRAM_NAME
35 : # error "You must define PROGRAM_NAME before including this header"
36 : #endif
37 :
38 : #ifdef __cplusplus
39 : extern "C" {
40 : #endif
41 :
42 : #ifndef MIN /* some C lib headers define this for us */
43 : #define MIN(a, b) ((a) < (b) ? (a) : (b))
44 : #endif
45 : #ifndef MAX
46 : #define MAX(a, b) ((a) > (b) ? (a) : (b))
47 : #endif
48 : #define min(a, b) MIN(a, b) /* glue for linux kernel source */
49 : #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
50 :
51 : #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
52 : #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
53 :
54 : #define min_t(t,x,y) ({ \
55 : typeof((x)) _x = (x); \
56 : typeof((y)) _y = (y); \
57 : (_x < _y) ? _x : _y; \
58 : })
59 :
60 : #define max_t(t,x,y) ({ \
61 : typeof((x)) _x = (x); \
62 : typeof((y)) _y = (y); \
63 : (_x > _y) ? _x : _y; \
64 : })
65 :
66 : /*
67 : * This looks more complex than it should be. But we need to
68 : * get the type for the ~ right in round_down (it needs to be
69 : * as wide as the result!), and we want to evaluate the macro
70 : * arguments just once each.
71 : */
72 : #define __round_mask(x, y) ((__typeof__(x))((y)-1))
73 : #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
74 : #define round_down(x, y) ((x) & ~__round_mask(x, y))
75 :
76 : #ifndef O_CLOEXEC
77 : #define O_CLOEXEC 0
78 : #endif
79 :
80 : /* Verbose messages */
81 : #define bareverbose(verbose, fmt, ...) do { \
82 : if (verbose) \
83 : printf(fmt, ##__VA_ARGS__); \
84 : } while(0)
85 : #define verbose(verbose, fmt, ...) \
86 : bareverbose(verbose, "%s: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__)
87 :
88 : /* Normal messages */
89 : #define normsg_cont(fmt, ...) do { \
90 : printf("%s: " fmt, PROGRAM_NAME, ##__VA_ARGS__); \
91 : } while(0)
92 : #define normsg(fmt, ...) do { \
93 : normsg_cont(fmt "\n", ##__VA_ARGS__); \
94 : } while(0)
95 :
96 : /* Error messages */
97 : #define errmsg(fmt, ...) ({ \
98 : fprintf(stderr, "%s: error!: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__); \
99 : -1; \
100 : })
101 : #define errmsg_die(fmt, ...) do { \
102 : exit(errmsg(fmt, ##__VA_ARGS__)); \
103 : } while(0)
104 :
105 : /* System error messages */
106 : #define sys_errmsg(fmt, ...) ({ \
107 : int _err = errno; \
108 : errmsg(fmt, ##__VA_ARGS__); \
109 : fprintf(stderr, "%*serror %d (%s)\n", (int)sizeof(PROGRAM_NAME) + 1,\
110 : "", _err, strerror(_err)); \
111 : -1; \
112 : })
113 : #define sys_errmsg_die(fmt, ...) do { \
114 : exit(sys_errmsg(fmt, ##__VA_ARGS__)); \
115 : } while(0)
116 :
117 : /* Warnings */
118 : #define warnmsg(fmt, ...) do { \
119 : fprintf(stderr, "%s: warning!: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__); \
120 : } while(0)
121 :
122 : /* for tagging functions that always exit */
123 : #if defined(__GNUC__) || defined(__clang__)
124 : #define NORETURN __attribute__((noreturn))
125 : #else
126 : #define NORETURN
127 : #endif
128 :
129 : /**
130 : * prompt the user for confirmation
131 : */
132 0 : static inline bool prompt(const char *msg, bool def)
133 : {
134 0 : bool ret = def;
135 : char line[64];
136 :
137 : do {
138 0 : normsg_cont("%s (%c/%c) ", msg, def ? 'Y' : 'y', def ? 'n' : 'N');
139 0 : fflush(stdout);
140 :
141 0 : if (fgets(line, sizeof(line), stdin) == NULL) {
142 0 : printf("failed to read prompt; assuming '%s'\n",
143 : def ? "yes" : "no");
144 0 : break;
145 : }
146 :
147 0 : if (strcmp("\n", line) != 0) {
148 0 : switch (line[0]) {
149 : case 'N':
150 : case 'n': ret = false; break;
151 0 : case 'Y':
152 0 : case 'y': ret = true; break;
153 0 : default:
154 0 : puts("unknown response; please try again");
155 0 : continue;
156 : }
157 0 : }
158 : break;
159 : } while (1);
160 :
161 0 : return ret;
162 : }
163 :
164 : static inline int is_power_of_2(unsigned long long n)
165 : {
166 834984 : return (n != 0 && ((n & (n - 1)) == 0));
167 : }
168 :
169 : /* Check whether buffer is filled with character 'pattern' */
170 : static inline int buffer_check_pattern(unsigned char *buffer, size_t size,
171 : unsigned char pattern)
172 : {
173 : /* Invalid input */
174 : if (!buffer || (size == 0))
175 : return 0;
176 :
177 : /* No match on first byte */
178 : if (*buffer != pattern)
179 : return 0;
180 :
181 : /* First byte matched and buffer is 1 byte long, OK. */
182 : if (size == 1)
183 : return 1;
184 :
185 : /*
186 : * Check buffer longer than 1 byte. We already know that buffer[0]
187 : * matches the pattern, so the test below only checks whether the
188 : * buffer[0...size-2] == buffer[1...size-1] , which is a test for
189 : * whether the buffer is filled with constant value.
190 : */
191 : return !memcmp(buffer, buffer + 1, size - 1);
192 : }
193 :
194 : /**
195 : * simple_strtoX - convert a hex/dec/oct string into a number
196 : * @snum: buffer to convert
197 : * @error: set to 1 when buffer isn't fully consumed
198 : *
199 : * These functions are similar to the standard strtoX() functions, but they are
200 : * a little bit easier to use if you want to convert full string of digits into
201 : * the binary form. The typical usage:
202 : *
203 : * int error = 0;
204 : * unsigned long num;
205 : *
206 : * num = simple_strtoul(str, &error);
207 : * if (error || ... if needed, your check that num is not out of range ...)
208 : * error_happened();
209 : */
210 : #define simple_strtoX(func, type) \
211 : static inline type simple_##func(const char *snum, int *error) \
212 : { \
213 : char *endptr; \
214 : type ret = func(snum, &endptr, 0); \
215 : \
216 : if (error && (!*snum || *endptr)) { \
217 : errmsg("%s: unable to parse the number '%s'", #func, snum); \
218 : *error = 1; \
219 : } \
220 : \
221 : return ret; \
222 : }
223 : simple_strtoX(strtol, long int)
224 : simple_strtoX(strtoll, long long int)
225 0 : simple_strtoX(strtoul, unsigned long int)
226 : simple_strtoX(strtoull, unsigned long long int)
227 :
228 : /* Simple version-printing for utils */
229 : #define common_print_version() \
230 : do { \
231 : printf("%s (mtd-utils) %s\n", PROGRAM_NAME, VERSION); \
232 : } while (0)
233 :
234 : #include "xalloc.h"
235 :
236 : long long util_get_bytes(const char *str);
237 : void util_print_bytes(long long bytes, int bracket);
238 : int util_srand(void);
239 : char *mtd_find_dev_node(const char *id);
240 :
241 : /*
242 : * The following helpers are here to avoid compiler complaints about unchecked
243 : * return code.
244 : * FIXME: The proper fix would be to check the return code in all those places,
245 : * but it's usually placed in old code which have no proper exit path and
246 : * handling errors requires rewriting a lot of code.
247 : *
248 : * WARNING: Please do not use these helpers in new code. Instead, make sure
249 : * you check the function return code and provide coherent error handling in
250 : * case of error.
251 : */
252 : static inline ssize_t read_nocheck(int fd, void *buf, size_t count)
253 : {
254 : return read(fd, buf, count);
255 : }
256 :
257 : static inline ssize_t write_nocheck(int fd, void *buf, size_t count)
258 : {
259 : return write(fd, buf, count);
260 : }
261 :
262 : static inline ssize_t pread_nocheck(int fd, void *buf, size_t count,
263 : off_t offset)
264 : {
265 : return pread(fd, buf, count, offset);
266 : }
267 :
268 : static inline ssize_t pwrite_nocheck(int fd, void *buf, size_t count,
269 : off_t offset)
270 : {
271 : return pwrite(fd, buf, count, offset);
272 : }
273 : #ifdef __cplusplus
274 : }
275 : #endif
276 :
277 : #endif /* !__MTD_UTILS_COMMON_H__ */
|