LCOV - code coverage report
Current view: top level - core - helper.h (source / functions) Coverage Total Hit
Test: lcov.out Lines: 79.2 % 24 19
Test Date: 2025-03-25 15:17:39 Functions: 75.0 % 4 3

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-2.0-only */
       2              : /*
       3              :  * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #pragma once
       7              : 
       8              : #include <assert.h>
       9              : #include <errno.h>
      10              : #include <stdbool.h>
      11              : #include <stddef.h>
      12              : #include <stdlib.h>
      13              : #include <string.h>
      14              : #include <unistd.h>
      15              : 
      16              : extern const char *strerrordesc_np(int errnum);
      17              : 
      18              : #define bf_packed __attribute__((packed))
      19              : #define bf_aligned(x) __attribute__((aligned(x)))
      20              : #define bf_unused __attribute__((unused))
      21              : 
      22              : #ifndef bf_assert
      23              : #define bf_assert(x) assert(x)
      24              : #endif
      25              : 
      26              : #define BF_STR(s) _BF_STR(s)
      27              : #define _BF_STR(s) #s
      28              : 
      29              : /**
      30              :  * Mark a variable as unused, to prevent the compiler from emitting a warning.
      31              :  *
      32              :  * @param x The variable to mark as unused.
      33              :  */
      34              : #define UNUSED(x) (void)(x)
      35              : 
      36              : /**
      37              :  * Set @p ptr to NULL and return its previous value.
      38              :  *
      39              :  * Inspired from systemd's TAKE_PTR() macro, which is itself inspired from
      40              :  * Rust's Option::take() method:
      41              :  * https://doc.rust-lang.org/std/option/enum.Option.html#method.take
      42              :  *
      43              :  * @param var Variable to return the value of.
      44              :  * @param type Type of @p var.
      45              :  * @param nullvalue Value to set @p var to.
      46              :  * @return Value of @p var before it was set to @p nullvalue.
      47              :  */
      48              : #define TAKE_GENERIC(var, type, nullvalue)                                     \
      49              :     ({                                                                         \
      50              :         /* NOLINTBEGIN: do not enclose 'type' in parentheses */                \
      51              :         type *_pvar_ = &(var);                                                 \
      52              :         type _var_ = *_pvar_;                                                  \
      53              :         type _nullvalue_ = nullvalue;                                          \
      54              :         /* NOLINTEND */                                                        \
      55              :         *_pvar_ = _nullvalue_;                                                 \
      56              :         _var_;                                                                 \
      57              :     })
      58              : 
      59              : #define TAKE_PTR_TYPE(ptr, type) TAKE_GENERIC(ptr, type, NULL)
      60              : #define TAKE_PTR(ptr) TAKE_PTR_TYPE(ptr, typeof(ptr))
      61              : #define TAKE_STRUCT_TYPE(s, type) TAKE_GENERIC(s, type, {})
      62              : #define TAKE_STRUCT(s) TAKE_STRUCT_TYPE(s, typeof(s))
      63              : #define TAKE_FD(fd) TAKE_GENERIC(fd, int, -1)
      64              : 
      65              : /**
      66              :  * Get the number of element in an array.
      67              :  *
      68              :  * @param x The array.
      69              :  * @return size_t The number of elements in the array.
      70              :  */
      71              : #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
      72              : 
      73              : #define _cleanup_free_ __attribute__((__cleanup__(freep)))
      74              : #define _cleanup_close_ __attribute__((__cleanup__(closep)))
      75              : 
      76              : /**
      77              :  * Return a string describing the given error code.
      78              :  *
      79              :  * This function must be used over strerror(), which is marked at mt-unsafe.
      80              :  *
      81              :  * @param v Error code, can be positive or negative.
      82              :  */
      83              : #define bf_strerror(v) strerrordesc_np(abs(v))
      84              : 
      85              : /**
      86              :  * Swap two values.
      87              :  *
      88              :  * @param a First value to swap.
      89              :  * @param b Second value to swap.
      90              :  */
      91              : #define bf_swap(a, b)                                                          \
      92              :     do {                                                                       \
      93              :         typeof(a) __a = (a);                                                   \
      94              :         (a) = (b);                                                             \
      95              :         (b) = __a;                                                             \
      96              :     } while (0)
      97              : 
      98              : #define bf_min(a, b)                                                           \
      99              :     ({                                                                         \
     100              :         __typeof__(a) _a = (a);                                                \
     101              :         __typeof__(b) _b = (b);                                                \
     102              :         _a < _b ? _a : _b;                                                     \
     103              :     })
     104              : 
     105              : /**
     106              :  * Free a pointer and set it to NULL.
     107              :  *
     108              :  * @param ptr Pointer to free.
     109              :  */
     110           84 : static inline void freep(void *ptr)
     111              : {
     112          542 :     free(*(void **)ptr);
     113          452 :     *(void **)ptr = NULL;
     114          102 : }
     115              : 
     116              : /**
     117              :  * Close a file descriptor and set it to -1.
     118              :  *
     119              :  * File descriptors are expected to be uninitialized to -1, so this function
     120              :  * can be used to close a file descriptor and set it to -1 in a single
     121              :  * operation. If the file descriptor is already -1, it is not closed.
     122              :  *
     123              :  * @param fd File descriptor to close.
     124              :  */
     125              : static inline void closep(int *fd)
     126              : {
     127           36 :     if (*fd >= 0)
     128           15 :         close(*fd);
     129           26 :     *fd = -1;
     130              : }
     131              : 
     132              : /**
     133              :  * Duplicate a memory region.
     134              :  *
     135              :  * Allocate a new buffer of size @p len and copy @p src into it. Requirements
     136              :  * applicable to @p src and @p len:
     137              :  * - If @p src is NULL, @p len must be 0. In this case, NULL is returned.
     138              :  * - If @p src is non-NULL, a new buffer of @p len bytes will be allocated to
     139              :  *   store the first @p len bytes of @p src. This new buffer is then returned.
     140              :  *
     141              :  * Unless NULL is returned, the new buffer is owned by the caller.
     142              :  *
     143              :  * @param src Source buffer to copy to @p dst.
     144              :  * @param len Number of bytes to copy to @p dst.
     145              :  * @return Pointer to the new buffer, or NULL on failure.
     146              :  */
     147            0 : static inline void *bf_memdup(const void *src, size_t len)
     148              : {
     149              :     void *dst;
     150              : 
     151            0 :     if (!src)
     152              :         return NULL;
     153              : 
     154            0 :     dst = malloc(len);
     155            0 :     if (!dst)
     156              :         return NULL;
     157              : 
     158            0 :     return memcpy(dst, src, len);
     159              : }
     160              : 
     161              : /**
     162              :  * Copy @p len bytes from @p src to @p dst.
     163              :  *
     164              :  * Allow for @p src to be NULL and/or @p len to be zero:
     165              :  * - If @p src is NULL, @p len must be equal 0. @p dst is not modified.
     166              :  * - If @p src is not NULL, @p len can be equal to 0, in which case @p dst is
     167              :  *   not modified.
     168              :  *
     169              :  * @param dst Destination buffer. Can't be NULL, and must be big enough to store
     170              :  *        @p len bytes from @p src.
     171              :  * @param src Source buffer to copy to @p dst.
     172              :  * @param len Number of bytes to copy to @p dst.
     173              :  * @return Pointer to @p dst.
     174              :  */
     175          173 : static inline void *bf_memcpy(void *dst, const void *src, size_t len)
     176              : {
     177          173 :     bf_assert(dst);
     178          173 :     bf_assert(src ? 1 : len == 0);
     179              : 
     180          173 :     if (!src || !len)
     181              :         return dst;
     182              : 
     183          125 :     return memcpy(dst, src, len);
     184              : }
     185              : 
     186              : /**
     187              :  * Reallocate @p ptr into a new buffer of size @p size.
     188              :  *
     189              :  * Behaves similarly to realloc(), except that @p ptr is left unchanged if
     190              :  * allocation fails, and an error is returned.
     191              :  *
     192              :  * @param ptr Memory buffer to grow. Can't be NULL.
     193              :  * @param size New size of the memory buffer.
     194              :  * @return 0 on success, or a negative errno value on failure.
     195              :  */
     196            4 : static inline int bf_realloc(void **ptr, size_t size)
     197              : {
     198              :     _cleanup_free_ void *_ptr;
     199              : 
     200            4 :     bf_assert(ptr);
     201              : 
     202            4 :     _ptr = realloc(*ptr, size);
     203            4 :     if (!_ptr)
     204              :         return -ENOMEM;
     205              : 
     206            4 :     *ptr = TAKE_PTR(_ptr);
     207              : 
     208            4 :     return 0;
     209              : }
     210              : 
     211              : /**
     212              :  * Returns true if @p a is equal to @p b.
     213              :  *
     214              :  * @param lhs First string.
     215              :  * @param rhs Second string.
     216              :  * @return True if @p a == @p b, false otherwise.
     217              :  */
     218              : static inline bool bf_streq(const char *lhs, const char *rhs) // NOLINT
     219              : {
     220          303 :     return strcmp(lhs, rhs) == 0;
     221              : }
     222              : 
     223              : /**
     224              :  * Copy a string to a buffer.
     225              :  *
     226              :  * @p src is copied to @p dst . If @p src is too long, at most @p len bytes are
     227              :  * copied (including the termination character).
     228              :  *
     229              :  * @param dst Destination buffer. Can't be NULL.
     230              :  * @param len Length of the destination buffer. The function will not copy more
     231              :  *        than @p len bytes to @p dst , including @c \0 . Can't be 0.
     232              :  * @param src Soucre buffer to copy from. Will only be copied up to the
     233              :  *        termination character if it fits. Can't be NULL.
     234              :  * @return 0 on success, or @c -E2BIG if @p src can't fit in @p dst .
     235              :  */
     236              : int bf_strncpy(char *dst, size_t len, const char *src);
     237              : 
     238              : /**
     239              :  * Read the contents of a file into a buffer.
     240              :  *
     241              :  * @param path Path to the file to read. Can't be NULL.
     242              :  * @param buf Pointer to a pointer to a buffer. The buffer will be allocated
     243              :  *        automatically. The caller is responsible to free it. If @ref bf_read_file
     244              :  *        fails, @p buf is left unchanged.
     245              :  * @param len Length of the allocated buffer. Populated by the function.
     246              :  * @return 0 on success, negative errno value on error.
     247              :  */
     248              : int bf_read_file(const char *path, void **buf, size_t *len);
     249              : 
     250              : /**
     251              :  * Write the contents of a buffer into a file.
     252              :  *
     253              :  * @param path Path to the file to write. Can't be NULL.
     254              :  * @param buf Buffer to write.
     255              :  * @param len Number of bytes to write the to file.
     256              :  * @return 0 on success, negative errno value on error.
     257              :  */
     258              : int bf_write_file(const char *path, const void *buf, size_t len);
        

Generated by: LCOV version 2.0-1