Skip to content

Commit

Permalink
Add safe readv()/writev() functions
Browse files Browse the repository at this point in the history
Add safe macros for vectorized I/O functions:
- SAFE_READV()
- SAFE_PREADV()
- SAFE_WRITEV()
- SAFE_PWRITEV()

Link: https://lore.kernel.org/ltp/[email protected]/
Reviewed-by: Petr Vorel <[email protected]>
Signed-off-by: Martin Doucha <[email protected]>
  • Loading branch information
mdoucha authored and pevik committed Nov 1, 2024
1 parent c84e514 commit 5746e25
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/lapi/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef LAPI_PREADV2_H__
#define LAPI_PREADV2_H__

#include <sys/uio.h>
#include "config.h"
#include "lapi/syscalls.h"

Expand Down
13 changes: 13 additions & 0 deletions include/tst_safe_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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__ */
58 changes: 58 additions & 0 deletions include/tst_safe_prw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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__ */
45 changes: 45 additions & 0 deletions lib/tst_safe_macros.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
}

0 comments on commit 5746e25

Please sign in to comment.