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

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

Generated by: LCOV version 1.0