[LTP] [PATCH v2 1/2] safe_macros: Add SAFE_READ_ANY_EAGAIN

Cyril Hrubis chrubis@suse.cz
Tue May 26 10:34:05 CEST 2026


Similarly to the safe_write() this turns the len_strict into three way
switch with the new value SAFE_READ_ANY_EAGAIN=2 that turns EAGAIN into
a read with a zero length.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 include/safe_macros_fn.h | 16 ++++++++++++++--
 lib/safe_macros.c        | 10 +++++++---
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/include/safe_macros_fn.h b/include/safe_macros_fn.h
index 9a09c4922..e8dc02539 100644
--- a/include/safe_macros_fn.h
+++ b/include/safe_macros_fn.h
@@ -36,6 +36,18 @@ enum safe_write_opts {
 	SAFE_WRITE_RETRY = 2,
 };
 
+/* supported values for safe_read() len_strict parameter */
+enum safe_read_opts {
+	/* no length strictness, short reads are ok */
+	SAFE_READ_ANY = 0,
+
+	/* strict length, short reads trigger TBROK */
+	SAFE_READ_ALL = 1,
+
+	/* converts EAGAIN to read that returns 0 */
+	SAFE_READ_ANY_EAGAIN = 2,
+};
+
 char* safe_basename(const char *file, const int lineno,
                     void (*cleanup_fn)(void), char *path);
 
@@ -80,8 +92,8 @@ int safe_pipe(const char *file, const int lineno,
               void (*cleanup_fn)(void), int fildes[2]);
 
 ssize_t safe_read(const char *file, const int lineno,
-                  void (*cleanup_fn)(void), char len_strict, int fildes,
-                  void *buf, size_t nbyte);
+                  void (*cleanup_fn)(void), enum safe_read_opts len_strict,
+                  int fildes, void *buf, size_t nbyte);
 
 int safe_setegid(const char *file, const int lineno,
                  void (*cleanup_fn)(void), gid_t egid);
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index 68b8747b4..f95c5fdc5 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -286,14 +286,18 @@ int safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void),
 	return rval;
 }
 
-ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void),
-                  char len_strict, int fildes, void *buf, size_t nbyte)
+ssize_t safe_read(const char *file, const int lineno,
+                  void (*cleanup_fn) (void), enum safe_read_opts len_strict,
+                  int fildes, void *buf, size_t nbyte)
 {
 	ssize_t rval;
 
 	rval = read(fildes, buf, nbyte);
 
 	if (rval == -1) {
+		if (len_strict == SAFE_READ_ANY_EAGAIN && errno == EAGAIN)
+			return 0;
+
 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
 			"read(%d,%p,%zu) failed, returned %zd", fildes, buf,
 			nbyte, rval);
@@ -301,7 +305,7 @@ ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void),
 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
 			"Invalid read(%d,%p,%zu) return value %zd", fildes,
 			buf, nbyte, rval);
-	} else if (len_strict && (size_t)rval != nbyte) {
+	} else if (len_strict == SAFE_READ_ALL && (size_t)rval != nbyte) {
 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
 			  "Short read(%d,%p,%zu) returned only %zd",
 			  fildes, buf, nbyte, rval);
-- 
2.53.0



More information about the ltp mailing list