1 /* SPDX-License-Identifier: GPL-2.0-or-later
2 * Copyright (c) 2010-2017 Linux Test Project
3 */
4
5 #ifndef TST_SAFE_PRW_H__
6 #define TST_SAFE_PRW_H__
7
8 #include "lapi/uio.h"
9
safe_pread(const char * file,const int lineno,char len_strict,int fildes,void * buf,size_t nbyte,off_t offset)10 static inline ssize_t safe_pread(const char *file, const int lineno,
11 char len_strict, int fildes, void *buf, size_t nbyte,
12 off_t offset)
13 {
14 ssize_t rval;
15
16 rval = pread(fildes, buf, nbyte, offset);
17
18 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) {
19 tst_brk_(file, lineno, TBROK | TERRNO,
20 "pread(%d,%p,%zu,%lld) failed",
21 fildes, buf, nbyte, (long long)offset);
22 } else if (rval < 0) {
23 tst_brk_(file, lineno, TBROK | TERRNO,
24 "Invalid pread(%d,%p,%zu,%lld) return value %zd",
25 fildes, buf, nbyte, (long long)offset, rval);
26 }
27
28 return rval;
29 }
30 #define SAFE_PREAD(len_strict, fildes, buf, nbyte, offset) \
31 safe_pread(__FILE__, __LINE__, (len_strict), (fildes), \
32 (buf), (nbyte), (offset))
33
safe_pwrite(const char * file,const int lineno,char len_strict,int fildes,const void * buf,size_t nbyte,off_t offset)34 static inline ssize_t safe_pwrite(const char *file, const int lineno,
35 char len_strict, int fildes, const void *buf, size_t nbyte,
36 off_t offset)
37 {
38 ssize_t rval;
39
40 rval = pwrite(fildes, buf, nbyte, offset);
41 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) {
42 tst_brk_(file, lineno, TBROK | TERRNO,
43 "pwrite(%d,%p,%zu,%lld) failed",
44 fildes, buf, nbyte, (long long)offset);
45 } else if (rval < 0) {
46 tst_brk_(file, lineno, TBROK | TERRNO,
47 "Invalid pwrite(%d,%p,%zu,%lld) return value %zd",
48 fildes, buf, nbyte, (long long)offset, rval);
49 }
50
51 return rval;
52 }
53 #define SAFE_PWRITE(len_strict, fildes, buf, nbyte, offset) \
54 safe_pwrite(__FILE__, __LINE__, (len_strict), (fildes), \
55 (buf), (nbyte), (offset))
56
safe_preadv(const char * file,const int lineno,char len_strict,int fildes,const struct iovec * iov,int iovcnt,off_t offset)57 static inline ssize_t safe_preadv(const char *file, const int lineno,
58 char len_strict, int fildes, const struct iovec *iov, int iovcnt,
59 off_t offset)
60 {
61 ssize_t rval, nbyte;
62 int i;
63
64 for (i = 0, nbyte = 0; i < iovcnt; i++)
65 nbyte += iov[i].iov_len;
66
67 rval = preadv(fildes, iov, iovcnt, offset);
68
69 if (rval == -1 || (len_strict && rval != nbyte)) {
70 tst_brk_(file, lineno, TBROK | TERRNO,
71 "preadv(%d,%p,%d,%lld) failed",
72 fildes, iov, iovcnt, (long long)offset);
73 } else if (rval < 0) {
74 tst_brk_(file, lineno, TBROK | TERRNO,
75 "Invalid preadv(%d,%p,%d,%lld) return value %zd",
76 fildes, iov, iovcnt, (long long)offset, rval);
77 }
78
79 return rval;
80 }
81 #define SAFE_PREADV(len_strict, fildes, iov, iovcnt, offset) \
82 safe_preadv(__FILE__, __LINE__, (len_strict), (fildes), \
83 (iov), (iovcnt), (offset))
84
safe_pwritev(const char * file,const int lineno,char len_strict,int fildes,const struct iovec * iov,int iovcnt,off_t offset)85 static inline ssize_t safe_pwritev(const char *file, const int lineno,
86 char len_strict, int fildes, const struct iovec *iov, int iovcnt,
87 off_t offset)
88 {
89 ssize_t rval, nbyte;
90 int i;
91
92 for (i = 0, nbyte = 0; i < iovcnt; i++)
93 nbyte += iov[i].iov_len;
94
95 rval = pwritev(fildes, iov, iovcnt, offset);
96
97 if (rval == -1 || (len_strict && rval != nbyte)) {
98 tst_brk_(file, lineno, TBROK | TERRNO,
99 "pwritev(%d,%p,%d,%lld) failed",
100 fildes, iov, iovcnt, (long long)offset);
101 } else if (rval < 0) {
102 tst_brk_(file, lineno, TBROK | TERRNO,
103 "Invalid pwritev(%d,%p,%d,%lld) return value %zd",
104 fildes, iov, iovcnt, (long long)offset, rval);
105 }
106
107 return rval;
108 }
109 #define SAFE_PWRITEV(len_strict, fildes, iov, iovcnt, offset) \
110 safe_pwritev(__FILE__, __LINE__, (len_strict), (fildes), \
111 (iov), (iovcnt), (offset))
112
113 #endif /* SAFE_PRW_H__ */
114