d1be2e5c92
Resolves: RHEL-1086,RHEL-22427,RHEL-22443
149 lines
6.0 KiB
Diff
149 lines
6.0 KiB
Diff
From 7c5ece0b649ebea23ebb28eb3cafdb28ba49a9d0 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
Date: Wed, 9 Aug 2023 18:21:13 +0200
|
|
Subject: [PATCH] errno-util: allow ERRNO_IS_* to accept types wider than int
|
|
|
|
This is useful if the variable is ssize_t and we don't want to trigger a
|
|
warning or truncation.
|
|
|
|
With gcc (gcc-13.2.1-1.fc38.x86_64), the resulting systemd binary is identical,
|
|
so I assume that the compiler is able to completely optimize away the type.
|
|
|
|
(cherry picked from commit fe0feacb9e9641874fde459af4067d9b7e9d7462)
|
|
|
|
Related: RHEL-22443
|
|
---
|
|
src/basic/errno-util.h | 27 +++++++++++++++------------
|
|
src/test/test-errno-util.c | 13 +++++++++++++
|
|
2 files changed, 28 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h
|
|
index be5c04e285..b10dd755c9 100644
|
|
--- a/src/basic/errno-util.h
|
|
+++ b/src/basic/errno-util.h
|
|
@@ -1,6 +1,7 @@
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#pragma once
|
|
|
|
+#include <inttypes.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
@@ -86,14 +87,16 @@ static inline int errno_or_else(int fallback) {
|
|
|
|
/* abs(3) says: Trying to take the absolute value of the most negative integer is not defined. */
|
|
#define _DEFINE_ABS_WRAPPER(name) \
|
|
- static inline bool ERRNO_IS_##name(int r) { \
|
|
- if (r == INT_MIN) \
|
|
+ static inline bool ERRNO_IS_##name(intmax_t r) { \
|
|
+ if (r == INTMAX_MIN) \
|
|
return false; \
|
|
- return ERRNO_IS_NEG_##name(-abs(r)); \
|
|
+ return ERRNO_IS_NEG_##name(-imaxabs(r)); \
|
|
}
|
|
|
|
+assert_cc(INT_MAX <= INTMAX_MAX);
|
|
+
|
|
/* For send()/recv() or read()/write(). */
|
|
-static inline bool ERRNO_IS_NEG_TRANSIENT(int r) {
|
|
+static inline bool ERRNO_IS_NEG_TRANSIENT(intmax_t r) {
|
|
return IN_SET(r,
|
|
-EAGAIN,
|
|
-EINTR);
|
|
@@ -107,7 +110,7 @@ _DEFINE_ABS_WRAPPER(TRANSIENT);
|
|
*
|
|
* Hint #3: When asynchronous connect() on TCP fails because the host never acknowledges a single packet,
|
|
* kernel tells us that with ETIMEDOUT, see tcp(7). */
|
|
-static inline bool ERRNO_IS_NEG_DISCONNECT(int r) {
|
|
+static inline bool ERRNO_IS_NEG_DISCONNECT(intmax_t r) {
|
|
return IN_SET(r,
|
|
-ECONNABORTED,
|
|
-ECONNREFUSED,
|
|
@@ -129,7 +132,7 @@ _DEFINE_ABS_WRAPPER(DISCONNECT);
|
|
|
|
/* Transient errors we might get on accept() that we should ignore. As per error handling comment in
|
|
* the accept(2) man page. */
|
|
-static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(int r) {
|
|
+static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(intmax_t r) {
|
|
return ERRNO_IS_NEG_DISCONNECT(r) ||
|
|
ERRNO_IS_NEG_TRANSIENT(r) ||
|
|
r == -EOPNOTSUPP;
|
|
@@ -137,7 +140,7 @@ static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(int r) {
|
|
_DEFINE_ABS_WRAPPER(ACCEPT_AGAIN);
|
|
|
|
/* Resource exhaustion, could be our fault or general system trouble */
|
|
-static inline bool ERRNO_IS_NEG_RESOURCE(int r) {
|
|
+static inline bool ERRNO_IS_NEG_RESOURCE(intmax_t r) {
|
|
return IN_SET(r,
|
|
-EMFILE,
|
|
-ENFILE,
|
|
@@ -146,7 +149,7 @@ static inline bool ERRNO_IS_NEG_RESOURCE(int r) {
|
|
_DEFINE_ABS_WRAPPER(RESOURCE);
|
|
|
|
/* Seven different errors for "operation/system call/ioctl/socket feature not supported" */
|
|
-static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(int r) {
|
|
+static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(intmax_t r) {
|
|
return IN_SET(r,
|
|
-EOPNOTSUPP,
|
|
-ENOTTY,
|
|
@@ -159,7 +162,7 @@ static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(int r) {
|
|
_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
|
|
|
|
/* Two different errors for access problems */
|
|
-static inline bool ERRNO_IS_NEG_PRIVILEGE(int r) {
|
|
+static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) {
|
|
return IN_SET(r,
|
|
-EACCES,
|
|
-EPERM);
|
|
@@ -167,7 +170,7 @@ static inline bool ERRNO_IS_NEG_PRIVILEGE(int r) {
|
|
_DEFINE_ABS_WRAPPER(PRIVILEGE);
|
|
|
|
/* Three different errors for "not enough disk space" */
|
|
-static inline bool ERRNO_IS_NEG_DISK_SPACE(int r) {
|
|
+static inline bool ERRNO_IS_NEG_DISK_SPACE(intmax_t r) {
|
|
return IN_SET(r,
|
|
-ENOSPC,
|
|
-EDQUOT,
|
|
@@ -176,7 +179,7 @@ static inline bool ERRNO_IS_NEG_DISK_SPACE(int r) {
|
|
_DEFINE_ABS_WRAPPER(DISK_SPACE);
|
|
|
|
/* Three different errors for "this device does not quite exist" */
|
|
-static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(int r) {
|
|
+static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(intmax_t r) {
|
|
return IN_SET(r,
|
|
-ENODEV,
|
|
-ENXIO,
|
|
@@ -186,7 +189,7 @@ _DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
|
|
|
|
/* Quite often we want to handle cases where the backing FS doesn't support extended attributes at all and
|
|
* where it simply doesn't have the requested xattr the same way */
|
|
-static inline bool ERRNO_IS_NEG_XATTR_ABSENT(int r) {
|
|
+static inline bool ERRNO_IS_NEG_XATTR_ABSENT(intmax_t r) {
|
|
return r == -ENODATA ||
|
|
ERRNO_IS_NEG_NOT_SUPPORTED(r);
|
|
}
|
|
diff --git a/src/test/test-errno-util.c b/src/test/test-errno-util.c
|
|
index 507d53df7a..cac0d5402b 100644
|
|
--- a/src/test/test-errno-util.c
|
|
+++ b/src/test/test-errno-util.c
|
|
@@ -52,6 +52,19 @@ TEST(ERRNO_IS_TRANSIENT) {
|
|
assert_se(!ERRNO_IS_NEG_TRANSIENT(EINTR));
|
|
assert_se( ERRNO_IS_TRANSIENT(-EINTR));
|
|
assert_se( ERRNO_IS_TRANSIENT(EINTR));
|
|
+
|
|
+ /* Test with type wider than int */
|
|
+ ssize_t r = -EAGAIN;
|
|
+ assert_se( ERRNO_IS_NEG_TRANSIENT(r));
|
|
+
|
|
+ /* On 64-bit arches, now (int) r == EAGAIN */
|
|
+ r = SSIZE_MAX - EAGAIN + 1;
|
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(r));
|
|
+
|
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INT_MAX));
|
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INT_MIN));
|
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INTMAX_MAX));
|
|
+ assert_se(!ERRNO_IS_NEG_TRANSIENT(INTMAX_MIN));
|
|
}
|
|
|
|
DEFINE_TEST_MAIN(LOG_INFO);
|