LCOV - code coverage report
Current view: top level - core - helper.h (source / functions) Coverage Total Hit
Test: lcov.out Lines: 75.0 % 24 18
Test Date: 2025-02-26 17:59:59 Functions: 50.0 % 4 2

            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              : /**
      99              :  * Free a pointer and set it to NULL.
     100              :  *
     101              :  * @param ptr Pointer to free.
     102              :  */
     103            0 : static inline void freep(void *ptr)
     104              : {
     105          121 :     free(*(void **)ptr);
     106           44 :     *(void **)ptr = NULL;
     107           18 : }
     108              : 
     109              : /**
     110              :  * Close a file descriptor and set it to -1.
     111              :  *
     112              :  * File descriptors are expected to be uninitialized to -1, so this function
     113              :  * can be used to close a file descriptor and set it to -1 in a single
     114              :  * operation. If the file descriptor is already -1, it is not closed.
     115              :  *
     116              :  * @param fd File descriptor to close.
     117              :  */
     118              : static inline void closep(int *fd)
     119              : {
     120           27 :     if (*fd >= 0)
     121            6 :         close(*fd);
     122           20 :     *fd = -1;
     123              : }
     124              : 
     125              : /**
     126              :  * Duplicate a memory region.
     127              :  *
     128              :  * Allocate a new buffer of size @p len and copy @p src into it. Requirements
     129              :  * applicable to @p src and @p len:
     130              :  * - If @p src is NULL, @p len must be 0. In this case, NULL is returned.
     131              :  * - If @p src is non-NULL, a new buffer of @p len bytes will be allocated to
     132              :  *   store the first @p len bytes of @p src. This new buffer is then returned.
     133              :  *
     134              :  * Unless NULL is returned, the new buffer is owned by the caller.
     135              :  *
     136              :  * @param src Source buffer to copy to @p dst.
     137              :  * @param len Number of bytes to copy to @p dst.
     138              :  * @return Pointer to the new buffer, or NULL on failure.
     139              :  */
     140            0 : static inline void *bf_memdup(const void *src, size_t len)
     141              : {
     142              :     void *dst;
     143              : 
     144            0 :     if (!src)
     145              :         return NULL;
     146              : 
     147            0 :     dst = malloc(len);
     148            0 :     if (!dst)
     149              :         return NULL;
     150              : 
     151            0 :     return memcpy(dst, src, len);
     152              : }
     153              : 
     154              : /**
     155              :  * Copy @p len bytes from @p src to @p dst.
     156              :  *
     157              :  * Allow for @p src to be NULL and/or @p len to be zero:
     158              :  * - If @p src is NULL, @p len must be equal 0. @p dst is not modified.
     159              :  * - If @p src is not NULL, @p len can be equal to 0, in which case @p dst is
     160              :  *   not modified.
     161              :  *
     162              :  * @param dst Destination buffer. Can't be NULL, and must be big enough to store
     163              :  *        @p len bytes from @p src.
     164              :  * @param src Source buffer to copy to @p dst.
     165              :  * @param len Number of bytes to copy to @p dst.
     166              :  * @return Pointer to @p dst.
     167              :  */
     168          172 : static inline void *bf_memcpy(void *dst, const void *src, size_t len)
     169              : {
     170          172 :     bf_assert(dst);
     171          172 :     bf_assert(src ? 1 : len == 0);
     172              : 
     173          172 :     if (!src || !len)
     174              :         return dst;
     175              : 
     176          125 :     return memcpy(dst, src, len);
     177              : }
     178              : 
     179              : /**
     180              :  * Reallocate @p ptr into a new buffer of size @p size.
     181              :  *
     182              :  * Behaves similarly to realloc(), except that @p ptr is left unchanged if
     183              :  * allocation fails, and an error is returned.
     184              :  *
     185              :  * @param ptr Memory buffer to grow. Can't be NULL.
     186              :  * @param size New size of the memory buffer.
     187              :  * @return 0 on success, or a negative errno value on failure.
     188              :  */
     189            4 : static inline int bf_realloc(void **ptr, size_t size)
     190              : {
     191              :     _cleanup_free_ void *_ptr;
     192              : 
     193            4 :     bf_assert(ptr);
     194              : 
     195            4 :     _ptr = realloc(*ptr, size);
     196            4 :     if (!_ptr)
     197              :         return -ENOMEM;
     198              : 
     199            4 :     *ptr = TAKE_PTR(_ptr);
     200              : 
     201            4 :     return 0;
     202              : }
     203              : 
     204              : /**
     205              :  * Returns true if @p a is equal to @p b.
     206              :  *
     207              :  * @param lhs First string.
     208              :  * @param rhs Second string.
     209              :  * @return True if @p a == @p b, false otherwise.
     210              :  */
     211              : static inline bool bf_streq(const char *lhs, const char *rhs) // NOLINT
     212              : {
     213          303 :     return strcmp(lhs, rhs) == 0;
     214              : }
     215              : 
     216              : /**
     217              :  * Read the contents of a file into a buffer.
     218              :  *
     219              :  * @param path Path to the file to read. Can't be NULL.
     220              :  * @param buf Pointer to a pointer to a buffer. The buffer will be allocated
     221              :  *        automatically. The caller is responsible to free it. If @ref bf_read_file
     222              :  *        fails, @p buf is left unchanged.
     223              :  * @param len Length of the allocated buffer. Populated by the function.
     224              :  * @return 0 on success, negative errno value on error.
     225              :  */
     226              : int bf_read_file(const char *path, void **buf, size_t *len);
     227              : 
     228              : /**
     229              :  * Write the contents of a buffer into a file.
     230              :  *
     231              :  * @param path Path to the file to write. Can't be NULL.
     232              :  * @param buf Buffer to write.
     233              :  * @param len Number of bytes to write the to file.
     234              :  * @return 0 on success, negative errno value on error.
     235              :  */
     236              : int bf_write_file(const char *path, const void *buf, size_t len);
        

Generated by: LCOV version 2.0-1