[LTP] [PATCH 2/5] Add safe readv()/writev() functions
Martin Doucha
mdoucha@suse.cz
Fri Nov 1 15:11:07 CET 2024
Add safe macros for vectorized I/O functions:
- SAFE_READV()
- SAFE_PREADV()
- SAFE_WRITEV()
- SAFE_PWRITEV()
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
include/lapi/uio.h | 1 +
include/tst_safe_macros.h | 13 +++++++++
include/tst_safe_prw.h | 58 +++++++++++++++++++++++++++++++++++++++
lib/tst_safe_macros.c | 45 ++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)
diff --git a/include/lapi/uio.h b/include/lapi/uio.h
index a78103d99..0ad2faacf 100644
--- a/include/lapi/uio.h
+++ b/include/lapi/uio.h
@@ -7,6 +7,7 @@
#ifndef LAPI_PREADV2_H__
#define LAPI_PREADV2_H__
+#include <sys/uio.h>
#include "config.h"
#include "lapi/syscalls.h"
diff --git a/include/tst_safe_macros.h b/include/tst_safe_macros.h
index 4df23e602..a9fa7dbe1 100644
--- a/include/tst_safe_macros.h
+++ b/include/tst_safe_macros.h
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include <sys/vfs.h>
#include <sys/sysinfo.h>
+#include <sys/uio.h>
#include <fcntl.h>
#include <libgen.h>
#include <signal.h>
@@ -515,4 +516,16 @@ int safe_symlinkat(const char *file, const int lineno,
#define SAFE_SYMLINKAT(oldpath, newdirfd, newpath) \
safe_symlinkat(__FILE__, __LINE__, (oldpath), (newdirfd), (newpath))
+ssize_t safe_readv(const char *file, const int lineno, char len_strict,
+ int fildes, const struct iovec *iov, int iovcnt);
+#define SAFE_READV(len_strict, fildes, iov, iovcnt) \
+ safe_readv(__FILE__, __LINE__, (len_strict), (fildes), \
+ (iov), (iovcnt))
+
+ssize_t safe_writev(const char *file, const int lineno, char len_strict,
+ int fildes, const struct iovec *iov, int iovcnt);
+#define SAFE_WRITEV(len_strict, fildes, iov, iovcnt) \
+ safe_writev(__FILE__, __LINE__, (len_strict), (fildes), \
+ (iov), (iovcnt))
+
#endif /* TST_SAFE_MACROS_H__ */
diff --git a/include/tst_safe_prw.h b/include/tst_safe_prw.h
index 2e506cb41..349fb46b4 100644
--- a/include/tst_safe_prw.h
+++ b/include/tst_safe_prw.h
@@ -5,6 +5,8 @@
#ifndef TST_SAFE_PRW_H__
#define TST_SAFE_PRW_H__
+#include "lapi/uio.h"
+
static inline ssize_t safe_pread(const char *file, const int lineno,
char len_strict, int fildes, void *buf, size_t nbyte,
off_t offset)
@@ -52,4 +54,60 @@ static inline ssize_t safe_pwrite(const char *file, const int lineno,
safe_pwrite(__FILE__, __LINE__, (len_strict), (fildes), \
(buf), (nbyte), (offset))
+static inline ssize_t safe_preadv(const char *file, const int lineno,
+ char len_strict, int fildes, const struct iovec *iov, int iovcnt,
+ off_t offset)
+{
+ ssize_t rval, nbyte;
+ int i;
+
+ for (i = 0, nbyte = 0; i < iovcnt; i++)
+ nbyte += iov[i].iov_len;
+
+ rval = preadv(fildes, iov, iovcnt, offset);
+
+ if (rval == -1 || (len_strict && rval != nbyte)) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "preadv(%d,%p,%d,%lld) failed",
+ fildes, iov, iovcnt, (long long)offset);
+ } else if (rval < 0) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "Invalid preadv(%d,%p,%d,%lld) return value %zd",
+ fildes, iov, iovcnt, (long long)offset, rval);
+ }
+
+ return rval;
+}
+#define SAFE_PREADV(len_strict, fildes, iov, iovcnt, offset) \
+ safe_preadv(__FILE__, __LINE__, (len_strict), (fildes), \
+ (iov), (iovcnt), (offset))
+
+static inline ssize_t safe_pwritev(const char *file, const int lineno,
+ char len_strict, int fildes, const struct iovec *iov, int iovcnt,
+ off_t offset)
+{
+ ssize_t rval, nbyte;
+ int i;
+
+ for (i = 0, nbyte = 0; i < iovcnt; i++)
+ nbyte += iov[i].iov_len;
+
+ rval = pwritev(fildes, iov, iovcnt, offset);
+
+ if (rval == -1 || (len_strict && rval != nbyte)) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "pwritev(%d,%p,%d,%lld) failed",
+ fildes, iov, iovcnt, (long long)offset);
+ } else if (rval < 0) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "Invalid pwritev(%d,%p,%d,%lld) return value %zd",
+ fildes, iov, iovcnt, (long long)offset, rval);
+ }
+
+ return rval;
+}
+#define SAFE_PWRITEV(len_strict, fildes, iov, iovcnt, offset) \
+ safe_pwritev(__FILE__, __LINE__, (len_strict), (fildes), \
+ (iov), (iovcnt), (offset))
+
#endif /* SAFE_PRW_H__ */
diff --git a/lib/tst_safe_macros.c b/lib/tst_safe_macros.c
index 868ebc08e..633b00404 100644
--- a/lib/tst_safe_macros.c
+++ b/lib/tst_safe_macros.c
@@ -732,6 +732,29 @@ int safe_prctl(const char *file, const int lineno,
return rval;
}
+ssize_t safe_readv(const char *file, const int lineno, char len_strict,
+ int fildes, const struct iovec *iov, int iovcnt)
+{
+ ssize_t rval, nbyte;
+ int i;
+
+ for (i = 0, nbyte = 0; i < iovcnt; i++)
+ nbyte += iov[i].iov_len;
+
+ rval = readv(fildes, iov, iovcnt);
+
+ if (rval == -1 || (len_strict && rval != nbyte)) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "readv(%d,%p,%d) failed", fildes, iov, iovcnt);
+ } else if (rval < 0) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "Invalid readv(%d,%p,%d) return value %zd",
+ fildes, iov, iovcnt, rval);
+ }
+
+ return rval;
+}
+
int safe_symlinkat(const char *file, const int lineno,
const char *oldpath, const int newdirfd, const char *newpath)
{
@@ -751,3 +774,25 @@ int safe_symlinkat(const char *file, const int lineno,
return rval;
}
+ssize_t safe_writev(const char *file, const int lineno, char len_strict,
+ int fildes, const struct iovec *iov, int iovcnt)
+{
+ ssize_t rval, nbyte;
+ int i;
+
+ for (i = 0, nbyte = 0; i < iovcnt; i++)
+ nbyte += iov[i].iov_len;
+
+ rval = writev(fildes, iov, iovcnt);
+
+ if (rval == -1 || (len_strict && rval != nbyte)) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "writev(%d,%p,%d) failed", fildes, iov, iovcnt);
+ } else if (rval < 0) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "Invalid writev(%d,%p,%d) return value %zd",
+ fildes, iov, iovcnt, rval);
+ }
+
+ return rval;
+}
--
2.46.0
More information about the ltp
mailing list