Line data Source code
1 : // SPDX-License-Identifier: GPL-3.0-or-later
2 : // Copyright (C) 2011 Andrea Mazzoleni
3 :
4 : #ifndef __SUPPORT_H
5 : #define __SUPPORT_H
6 :
7 : /****************************************************************************/
8 : /* lock */
9 :
10 : /**
11 : * Initialize and destroy the locks.
12 : */
13 : void lock_init(void);
14 : void lock_done(void);
15 :
16 : /**
17 : * Lock used for printf.
18 : *
19 : * In Windows printf() is not atomic, and multiple threads
20 : * will have output interleaved.
21 : *
22 : * Note that even defining __USE_MINGW_ANSI_STDIO the problem persists.
23 : *
24 : * See for example:
25 : *
26 : * Weird output when I use pthread and printf.
27 : * http://stackoverflow.com/questions/13190254/weird-output-when-i-use-pthread-and-printf
28 : *
29 : * This is also required in other OS because we split output in stdlog in
30 : * two fprintf calls.
31 : */
32 : void lock_msg(void);
33 : void unlock_msg(void);
34 :
35 : /**
36 : * Lock used for memory counter.
37 : */
38 : void lock_memory(void);
39 : void unlock_memory(void);
40 :
41 : /****************************************************************************/
42 : /* random */
43 :
44 : /**
45 : * Seed the random pseudo random number generator
46 : */
47 : void random_seed(uint64_t seed);
48 :
49 : /**
50 : * Reseed the random pseudo random number generator with the tick count
51 : */
52 : void random_reseed(void);
53 :
54 : /**
55 : * Return a pseudo random number of 8 bits
56 : */
57 : unsigned char random_u8(void);
58 :
59 : /**
60 : * Return a pseudo random number of 64 bits
61 : */
62 : uint64_t random_u64(void);
63 :
64 : /****************************************************************************/
65 : /* error */
66 :
67 : /**
68 : * Return if the error is at hardware level
69 : */
70 : int is_hw(int err);
71 :
72 : /**
73 : * Log errors with standard messages
74 : */
75 : void log_fatal_errno(int err, const char* name);
76 : void log_error_errno(int err, const char* name);
77 :
78 : /****************************************************************************/
79 : /* log */
80 :
81 : /**
82 : * Pointer to log function.
83 : */
84 : typedef void log_ptr(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
85 :
86 : /**
87 : * Fatal error messages.
88 : *
89 : * Messages printed before an early termination.
90 : *
91 : * These messages go in the log file and in stderr unconditionally.
92 : */
93 : void log_fatal(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
94 :
95 : /**
96 : * Unexpected error messages.
97 : *
98 : * Messages reporting error conditions that don't prevent the program to run.
99 : *
100 : * Some of them could be also serious errors, like "silent errors".
101 : * In such case, the summary result is always printed as error,
102 : * and we are sure to notify the user in some way.
103 : *
104 : * These messages go in the log file if specified, otherwise they go in stderr.
105 : */
106 : void log_error(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
107 :
108 : /**
109 : * Expected error messages, without fallback to stderr.
110 : *
111 : * These errors are "someway" expected, and then they never go to screen.
112 : * For example, when undeleting missing files, the messages for missing files
113 : * are not shown.
114 : *
115 : * These messages go in the log file if specified, otherwise they are lost.
116 : */
117 : void log_expected(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
118 :
119 : /**
120 : * Tag messages.
121 : *
122 : * Messages are in tag format, like "tag:entry:...".
123 : *
124 : * These messages never go on the screen, but only in the log file if specified.
125 : *
126 : * Note that this function, allows not \n terminated strings.
127 : *
128 : * These messages are buffered. Use msg_flush() to flush them.
129 : */
130 : void log_tag(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
131 :
132 : /**
133 : * Flush the log.
134 : */
135 : void log_flush(void);
136 :
137 : /****************************************************************************/
138 : /* message */
139 :
140 : /**
141 : * Pointer to msg function.
142 : */
143 : typedef void msg_ptr(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
144 :
145 : /**
146 : * Message levels.
147 : *
148 : * The levels control the amount of information printed on the screen.
149 : * Note that log_fatal(), log_error(), log_expected() and log_tag() are not affected by this option.
150 : *
151 : * From the most quiet to the most verbose.
152 : */
153 : #define MSG_STATUS -3
154 : #define MSG_INFO -2
155 : #define MSG_PROGRESS -1
156 : #define MSG_BAR 0
157 : #define MSG_VERBOSE 1
158 :
159 : /**
160 : * Selected message level.
161 : */
162 : extern int msg_level;
163 :
164 : /**
165 : * State messages.
166 : *
167 : * Messages that tell what the program is doing or did, but limited to few lines.
168 : * They are status information, and summary results.
169 : */
170 : void msg_status(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
171 :
172 : /**
173 : * Info messages.
174 : *
175 : * Messages that tell what was done.
176 : * Potentially a lot of messages are possible. They can still be on the screen,
177 : * as losing them we don't lose information.
178 : *
179 : * These messages never go in the log file, because there is always a corresponding log_tag().
180 : */
181 : void msg_info(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
182 :
183 : /**
184 : * Progress messages.
185 : *
186 : * Message that tell the progress of program.
187 : *
188 : * These messages also go in the log file.
189 : */
190 : void msg_progress(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
191 :
192 : /**
193 : * Progress bar messages.
194 : *
195 : * Message that show the percentage of the progress.
196 : *
197 : * These messages never go in the log file.
198 : *
199 : * These messages are buffered. Use msg_flush() to flush them.
200 : */
201 : void msg_bar(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
202 :
203 : /**
204 : * Verbose messages.
205 : *
206 : * Message that tell what is already expected.
207 : *
208 : * These messages also go in the log file.
209 : */
210 : void msg_verbose(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
211 :
212 : /**
213 : * Flush the output.
214 : */
215 : void msg_flush(void);
216 :
217 : /****************************************************************************/
218 : /* print */
219 :
220 : /**
221 : * Print a repeated char.
222 : */
223 : void printc(char c, size_t pad);
224 :
225 : /**
226 : * Print a string with right space padding.
227 : */
228 : void printr(const char* str, size_t pad);
229 :
230 : /**
231 : * Print a string with left space padding.
232 : */
233 : void printl(const char* str, size_t pad);
234 :
235 : /**
236 : * Print a probability with space padding.
237 : */
238 : void printp(double v, size_t pad);
239 :
240 : /****************************************************************************/
241 : /* string */
242 :
243 : #define ESC_MAX (PATH_MAX * 2 + 1)
244 :
245 : /**
246 : * Escape a string for the log.
247 : *
248 : * \param buffer Preallocated buffer of ESC_MAX size.
249 : *
250 : * Chars ':', '\n', '\r' and '\' are escaped to '\d', '\\n', '\\r' and '\\'.
251 : */
252 : const char* esc_tag(const char* str, char* buffer);
253 :
254 : /**
255 : * Escape a string for the shell.
256 : *
257 : * \param buffer Preallocated buffer of ESC_MAX size.
258 : */
259 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer);
260 365619 : static inline const char* esc_shell(const char* str, char* buffer)
261 : {
262 365619 : return esc_shell_multi(&str, 1, buffer);
263 : }
264 :
265 : /**
266 : * Polish a string.
267 : *
268 : * Not printable chars are replaced by spaces.
269 : *
270 : * Note that the passed string is modified.
271 : */
272 : char* strpolish(char* s);
273 :
274 : /**
275 : * Split a string in multiple tokens separated by delimiters.
276 : *
277 : * Multiple delimiters are grouped together.
278 : */
279 : unsigned strsplit(char** split_map, unsigned split_max, char* line, const char* delimiters);
280 :
281 : /**
282 : * Trim spaces from the start and the end
283 : */
284 : char* strtrim(char* s);
285 :
286 : /**
287 : * Lower case
288 : */
289 : char* strlwr(char* s);
290 :
291 : /*
292 : * Find the first occurrence of 'needle' in 'haystack' only if it
293 : * appears as a separate word (space, number or string boundaries).
294 : *
295 : * Returns a pointer to the beginning of the match, or NULL if not found.
296 : */
297 : char* worddigitstr(const char* haystack, const char* needle);
298 :
299 : /****************************************************************************/
300 : /* path */
301 :
302 : /**
303 : * Copy a path limiting the size.
304 : * Abort if too long.
305 : */
306 : void pathcpy(char* dst, size_t size, const char* src);
307 :
308 : /**
309 : * Concatenate a path limiting the size.
310 : * Abort if too long.
311 : */
312 : void pathcat(char* dst, size_t size, const char* src);
313 :
314 : /**
315 : * Concatenate a path limiting the size knowing the length.
316 : * Abort if too long.
317 : */
318 : void pathcatl(char* dst, size_t dst_len, size_t size, const char* src);
319 :
320 : /**
321 : * Concatenate a path limiting the size.
322 : * Abort if too long.
323 : */
324 : void pathcatc(char* dst, size_t size, char c);
325 :
326 : /**
327 : * Import a path limiting the size.
328 : * In Windows all the backslash are converted to the C standard of forward slash.
329 : * Abort if too long.
330 : */
331 : void pathimport(char* dst, size_t size, const char* src);
332 :
333 : /**
334 : * Export a path limiting the size.
335 : * In Windows all the C slashes are converted to the Windows backslash.
336 : * Abort if too long.
337 : */
338 : void pathexport(char* dst, size_t size, const char* src);
339 :
340 : /**
341 : * Print a path.
342 : * Abort if too long.
343 : */
344 : void pathprint(char* dst, size_t size, const char* format, ...) __attribute__((format(attribute_printf, 3, 4)));
345 :
346 : /**
347 : * Ensure the presence of a terminating slash, if it isn't empty.
348 : * Abort if too long.
349 : */
350 : void pathslash(char* dst, size_t size);
351 :
352 : /**
353 : * Cut everything after the latest slash.
354 : *
355 : * If the string doesn't contain any slash, it returns the empty string.
356 : */
357 : void pathcut(char* dst);
358 :
359 : /**
360 : * Given a string ending with slash, remove that ending slash and any char up to the previous slash.
361 : *
362 : * If there are not more slash, it returns the empty string.
363 : */
364 : void pathup(char* dst);
365 :
366 : /**
367 : * Compare two paths.
368 : * In Windows it's case insensitive and assumes \ equal at /.
369 : */
370 : int pathcmp(const char* a, const char* b);
371 :
372 : /**
373 : * Check if the root is matching the start of the specified path.
374 : *
375 : * The root MUST end with a /.
376 : *
377 : * In Windows it's case insensitive and assumes \ equal at /.
378 : */
379 : int path_is_root_of(const char* root, const char* path);
380 :
381 : /****************************************************************************/
382 : /* file-system */
383 :
384 : /**
385 : * Create all the ancestor directories if missing.
386 : * The file name, after the last /, is ignored.
387 : */
388 : int mkancestor(const char* file);
389 :
390 : /**
391 : * Change the modification time of an open file.
392 : */
393 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec);
394 :
395 : /**
396 : * Change the modification time of a file or link.
397 : * Note that links are NOT deferenced.
398 : */
399 : int lmtime(const char* path, int64_t mtime_sec, int mtime_nsec);
400 :
401 : /****************************************************************************/
402 : /* advise */
403 :
404 : /**
405 : * Advise modes.
406 : */
407 : #define ADVISE_DEFAULT 0 /**< Default mode. */
408 : #define ADVISE_NONE 1 /**< Bare read/write mode. */
409 : #define ADVISE_SEQUENTIAL 2 /**< Sequential mode. */
410 : #define ADVISE_FLUSH 3 /**< Flush mode. */
411 : #define ADVISE_FLUSH_WINDOW 4 /**< Flush mode with a window of 8MB. */
412 : #define ADVISE_DISCARD 5 /**< Discard the cache after every operation. */
413 : #define ADVISE_DISCARD_WINDOW 6 /**< Discard the cache with a window of 8MB. */
414 : #define ADVISE_DIRECT 7 /**< Direct mode. */
415 :
416 : #define ADVISE_WINDOW_SIZE (8 * 1024 * 1024) /**< Window size. */
417 :
418 : struct advise_struct {
419 : int mode;
420 : data_off_t dirty_begin;
421 : data_off_t dirty_end;
422 : };
423 :
424 : void advise_init(struct advise_struct* advise, int mode);
425 : int advise_flags(struct advise_struct* advise);
426 : int advise_open(struct advise_struct* advise, int f);
427 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
428 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
429 :
430 : /****************************************************************************/
431 : /* memory */
432 :
433 : /**
434 : * Return the size of the allocated memory.
435 : */
436 : size_t malloc_counter_get(void);
437 :
438 : /**
439 : * Safe malloc.
440 : * If no memory is available, it aborts.
441 : */
442 : void* malloc_nofail(size_t size);
443 :
444 : /**
445 : * Safe cmalloc.
446 : * If no memory is available, it aborts.
447 : */
448 : void* calloc_nofail(size_t count, size_t size);
449 :
450 : /**
451 : * Safe strdup.
452 : * If no memory is available, it aborts.
453 : */
454 : char* strdup_nofail(const char* str);
455 :
456 : /**
457 : * Helper for printing an error about a failed allocation.
458 : */
459 : void malloc_fail(size_t size);
460 :
461 : /****************************************************************************/
462 : /* smartctl */
463 :
464 : /**
465 : * Read smartctl attributes from a stream.
466 : * Return 0 on success.
467 : */
468 : int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interf);
469 :
470 : /**
471 : * Flush smartctl output from a stream.
472 : */
473 : int smartctl_flush(FILE* f, const char* file, const char* name);
474 :
475 : /**
476 : * Extract the temperature from the SMART info.
477 : * Return -1 if missing
478 : */
479 : int smart_temp(devinfo_t* devinfo);
480 :
481 : /****************************************************************************/
482 : /* thread */
483 :
484 : #if HAVE_THREAD
485 : /**
486 : * Control when to signal the condition variables.
487 : *
488 : * Default is inside the mutex.
489 : *
490 : * Ensure to change that before starting any thread.
491 : */
492 : extern int thread_cond_signal_outside;
493 :
494 : /**
495 : * Thread wrappers to handle error conditions.
496 : */
497 : void thread_mutex_init(thread_mutex_t* mutex);
498 : void thread_mutex_destroy(thread_mutex_t* mutex);
499 : void thread_mutex_lock(thread_mutex_t* mutex);
500 : void thread_mutex_unlock(thread_mutex_t* mutex);
501 : void thread_cond_init(thread_cond_t* cond);
502 : void thread_cond_destroy(thread_cond_t* cond);
503 : void thread_cond_signal(thread_cond_t* cond);
504 : void thread_cond_broadcast(thread_cond_t* cond);
505 : void thread_cond_wait(thread_cond_t* cond, thread_mutex_t* mutex);
506 : void thread_cond_signal_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex);
507 : void thread_cond_broadcast_and_unlock(thread_cond_t* cond, thread_mutex_t* mutex);
508 : void thread_create(thread_id_t* thread, void* (*func)(void*), void* arg);
509 : void thread_join(thread_id_t thread, void** retval);
510 : void thread_yield(void);
511 : #endif
512 :
513 : /****************************************************************************/
514 : /* match */
515 :
516 : /*
517 : * Wild match function.
518 : *
519 : * If match_sub is !=0, it matches sub directory. Specifically it matches if the
520 : * string "t" is not fully consumed and the next character to consume is a /.
521 : *
522 : * - ? matches any single character except /
523 : * - * matches any sequence of characters except /
524 : * - ** (nearby a /) matches everything including /
525 : * - ** (not near a /) like *
526 : * - ##/ reduces to nothing in addition to the normal matching of ** (using # instead of * to not mess the C comment)
527 : * - [...] matches character classes with support for ranges and negation lile [!...] or [^...], except /
528 : *
529 : * \return 0 if it matches
530 : */
531 : int wnmatch_sub(const char* p, const char* t, int match_sub);
532 :
533 141578 : static inline int wnmatch(const char* p, const char* t)
534 : {
535 141578 : return wnmatch_sub(p, t, 0);
536 : }
537 :
538 : #endif
539 :
|