LCOV - code coverage report
Current view: top level - cmdline - support.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 4 4 100.0 %
Date: 2026-04-29 15:04:44 Functions: 2 2 100.0 %

          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             : 

Generated by: LCOV version 1.0