LCOV - code coverage report
Current view: top level - basic - errno-util.h (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 14 20 70.0 %
Date: 2019-08-22 15:41:25 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : #pragma once
       3             : 
       4             : #include <stdlib.h>
       5             : #include <string.h>
       6             : 
       7             : #include "macro.h"
       8             : 
       9      233757 : static inline void _reset_errno_(int *saved_errno) {
      10      233757 :         if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
      11           1 :                 return;
      12             : 
      13      233756 :         errno = *saved_errno;
      14             : }
      15             : 
      16             : #define PROTECT_ERRNO                                                   \
      17             :         _cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno
      18             : 
      19             : #define UNPROTECT_ERRNO                         \
      20             :         do {                                    \
      21             :                 errno = _saved_errno_;          \
      22             :                 _saved_errno_ = -1;             \
      23             :         } while (false)
      24             : 
      25           0 : static inline int negative_errno(void) {
      26             :         /* This helper should be used to shut up gcc if you know 'errno' is
      27             :          * negative. Instead of "return -errno;", use "return negative_errno();"
      28             :          * It will suppress bogus gcc warnings in case it assumes 'errno' might
      29             :          * be 0 and thus the caller's error-handling might not be triggered. */
      30           0 :         assert_return(errno > 0, -EINVAL);
      31           0 :         return -errno;
      32             : }
      33             : 
      34         112 : static inline const char *strerror_safe(int error) {
      35             :         /* 'safe' here does NOT mean thread safety. */
      36         112 :         return strerror(abs(error));
      37             : }
      38             : 
      39         141 : static inline int errno_or_else(int fallback) {
      40             :         /* To be used when invoking library calls where errno handling is not defined clearly: we return
      41             :          * errno if it is set, and the specified error otherwise. The idea is that the caller initializes
      42             :          * errno to zero before doing an API call, and then uses this helper to retrieve a somewhat useful
      43             :          * error code */
      44         141 :         if (errno > 0)
      45           3 :                 return -errno;
      46             : 
      47         138 :         return -abs(fallback);
      48             : }
      49             : 
      50             : /* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5.
      51             :  *
      52             :  * Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases.  See the
      53             :  *          icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */
      54         305 : static inline bool ERRNO_IS_DISCONNECT(int r) {
      55         305 :         return IN_SET(abs(r),
      56             :                       ECONNABORTED,
      57             :                       ECONNREFUSED,
      58             :                       ECONNRESET,
      59             :                       EHOSTDOWN,
      60             :                       EHOSTUNREACH,
      61             :                       ENETDOWN,
      62             :                       ENETRESET,
      63             :                       ENETUNREACH,
      64             :                       ENONET,
      65             :                       ENOPROTOOPT,
      66             :                       ENOTCONN,
      67             :                       EPIPE,
      68             :                       EPROTO,
      69             :                       ESHUTDOWN);
      70             : }
      71             : 
      72             : /* Transient errors we might get on accept() that we should ignore. As per error handling comment in
      73             :  * the accept(2) man page. */
      74           0 : static inline bool ERRNO_IS_ACCEPT_AGAIN(int r) {
      75           0 :         return ERRNO_IS_DISCONNECT(r) ||
      76           0 :                 IN_SET(abs(r),
      77             :                        EAGAIN,
      78             :                        EINTR,
      79             :                        EOPNOTSUPP);
      80             : }
      81             : 
      82             : /* Resource exhaustion, could be our fault or general system trouble */
      83          82 : static inline bool ERRNO_IS_RESOURCE(int r) {
      84          82 :         return IN_SET(abs(r),
      85             :                       EMFILE,
      86             :                       ENFILE,
      87             :                       ENOMEM);
      88             : }

Generated by: LCOV version 1.14