blob: 42e7d98c7318a1f3f1db6c2985e0a649d0626029 [file] [log] [blame]
Zeng Linggang91d67422014-04-25 10:46:32 +08001#define _GNU_SOURCE
Garrett Cooperdd3f47e2010-12-20 05:40:52 -08002#include <sys/types.h>
Garrett Cooperca435922010-12-20 12:26:32 -08003#include <sys/mman.h>
Caspar Zhang817c7822011-06-30 01:50:33 +08004#include <sys/resource.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -08005#include <sys/stat.h>
Cyril Hrubisf3e448f2014-04-24 14:24:49 +02006#include <sys/wait.h>
Matus Marhefka8e9db8d2014-08-29 14:22:11 +02007#include <sys/mount.h>
Dejan Jovicevic10552812016-11-15 13:19:33 +01008#include <sys/xattr.h>
Vinson Lee9af0bd72012-02-09 15:05:50 -08009#include <errno.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080010#include <fcntl.h>
11#include <libgen.h>
Caspar Zhangd6a1f252012-02-09 15:58:28 +080012#include <limits.h>
Garrett Cooperca435922010-12-20 12:26:32 -080013#include <pwd.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080014#include <stdarg.h>
Garrett Cooperca435922010-12-20 12:26:32 -080015#include <stdlib.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080016#include <unistd.h>
Zeng Linggang5ff25ef2014-05-06 15:49:42 +080017#include <malloc.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080018#include "test.h"
Garrett Cooperca435922010-12-20 12:26:32 -080019#include "safe_macros.h"
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080020
Wanlong Gao354ebb42012-12-07 10:10:04 +080021char *safe_basename(const char *file, const int lineno,
22 void (*cleanup_fn) (void), char *path)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080023{
24 char *rval;
25
26 rval = basename(path);
Mats Liljegren49e86152014-04-16 19:27:58 +020027 if (rval == NULL) {
28 tst_brkm(TBROK | TERRNO, cleanup_fn,
29 "%s:%d: basename(%s) failed",
30 file, lineno, path);
31 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080032
Mats Liljegren49e86152014-04-16 19:27:58 +020033 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080034}
35
36int
Wanlong Gao354ebb42012-12-07 10:10:04 +080037safe_chdir(const char *file, const int lineno, void (*cleanup_fn) (void),
38 const char *path)
Garrett Cooper4a3c6582010-12-21 07:07:01 -080039{
40 int rval;
41
42 rval = chdir(path);
Mats Liljegren49e86152014-04-16 19:27:58 +020043 if (rval == -1) {
44 tst_brkm(TBROK | TERRNO, cleanup_fn,
45 "%s:%d: chdir(%s) failed",
46 file, lineno, path);
47 }
Garrett Cooper4a3c6582010-12-21 07:07:01 -080048
Mats Liljegren49e86152014-04-16 19:27:58 +020049 return rval;
Garrett Cooper4a3c6582010-12-21 07:07:01 -080050}
51
52int
Wanlong Gao354ebb42012-12-07 10:10:04 +080053safe_close(const char *file, const int lineno, void (*cleanup_fn) (void),
54 int fildes)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080055{
56 int rval;
57
58 rval = close(fildes);
Mats Liljegren49e86152014-04-16 19:27:58 +020059 if (rval == -1) {
60 tst_brkm(TBROK | TERRNO, cleanup_fn,
61 "%s:%d: close(%d) failed",
62 file, lineno, fildes);
63 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080064
Mats Liljegren49e86152014-04-16 19:27:58 +020065 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080066}
67
68int
Wanlong Gao354ebb42012-12-07 10:10:04 +080069safe_creat(const char *file, const int lineno, void (*cleanup_fn) (void),
Alexey Kodanev5071db52015-04-15 11:03:29 +030070 const char *pathname, mode_t mode)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080071{
72 int rval;
73
74 rval = creat(pathname, mode);
Mats Liljegren49e86152014-04-16 19:27:58 +020075 if (rval == -1) {
76 tst_brkm(TBROK | TERRNO, cleanup_fn,
77 "%s:%d: creat(%s,0%o) failed",
78 file, lineno, pathname, mode);
79 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080080
Mats Liljegren49e86152014-04-16 19:27:58 +020081 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080082}
83
Wanlong Gao354ebb42012-12-07 10:10:04 +080084char *safe_dirname(const char *file, const int lineno,
85 void (*cleanup_fn) (void), char *path)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080086{
87 char *rval;
88
89 rval = dirname(path);
Mats Liljegren49e86152014-04-16 19:27:58 +020090 if (rval == NULL) {
91 tst_brkm(TBROK | TERRNO, cleanup_fn,
92 "%s:%d: dirname(%s) failed",
93 file, lineno, path);
94 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080095
Mats Liljegren49e86152014-04-16 19:27:58 +020096 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080097}
98
Wanlong Gao354ebb42012-12-07 10:10:04 +080099char *safe_getcwd(const char *file, const int lineno, void (*cleanup_fn) (void),
100 char *buf, size_t size)
Garrett Cooperca435922010-12-20 12:26:32 -0800101{
102 char *rval;
103
104 rval = getcwd(buf, size);
Mats Liljegren49e86152014-04-16 19:27:58 +0200105 if (rval == NULL) {
106 tst_brkm(TBROK | TERRNO, cleanup_fn,
107 "%s:%d: getcwd(%p,%zu) failed",
108 file, lineno, buf, size);
109 }
Garrett Cooperca435922010-12-20 12:26:32 -0800110
Mats Liljegren49e86152014-04-16 19:27:58 +0200111 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800112}
113
Wanlong Gao354ebb42012-12-07 10:10:04 +0800114struct passwd *safe_getpwnam(const char *file, const int lineno,
115 void (*cleanup_fn) (void), const char *name)
Garrett Cooperca435922010-12-20 12:26:32 -0800116{
117 struct passwd *rval;
118
119 rval = getpwnam(name);
Mats Liljegren49e86152014-04-16 19:27:58 +0200120 if (rval == NULL) {
121 tst_brkm(TBROK | TERRNO, cleanup_fn,
122 "%s:%d: getpwnam(%s) failed",
123 file, lineno, name);
124 }
Garrett Cooperca435922010-12-20 12:26:32 -0800125
Mats Liljegren49e86152014-04-16 19:27:58 +0200126 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800127}
128
Caspar Zhang817c7822011-06-30 01:50:33 +0800129int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800130safe_getrusage(const char *file, const int lineno, void (*cleanup_fn) (void),
131 int who, struct rusage *usage)
Caspar Zhang817c7822011-06-30 01:50:33 +0800132{
133 int rval;
134
135 rval = getrusage(who, usage);
Mats Liljegren49e86152014-04-16 19:27:58 +0200136 if (rval == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800137 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200138 "%s:%d: getrusage(%d,%p) failed",
139 file, lineno, who, usage);
140 }
Caspar Zhang817c7822011-06-30 01:50:33 +0800141
142 return rval;
143}
144
Wanlong Gao354ebb42012-12-07 10:10:04 +0800145void *safe_malloc(const char *file, const int lineno, void (*cleanup_fn) (void),
146 size_t size)
Garrett Cooperca435922010-12-20 12:26:32 -0800147{
148 void *rval;
149
150 rval = malloc(size);
Mats Liljegren49e86152014-04-16 19:27:58 +0200151 if (rval == NULL) {
152 tst_brkm(TBROK | TERRNO, cleanup_fn,
153 "%s:%d: malloc(%zu) failed",
154 file, lineno, size);
155 }
Garrett Cooperca435922010-12-20 12:26:32 -0800156
Mats Liljegren49e86152014-04-16 19:27:58 +0200157 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800158}
159
Mats Liljegren49e86152014-04-16 19:27:58 +0200160int safe_mkdir(const char *file, const int lineno, void (*cleanup_fn) (void),
161 const char *pathname, mode_t mode)
Garrett Cooper4a3c6582010-12-21 07:07:01 -0800162{
163 int rval;
164
165 rval = mkdir(pathname, mode);
Mats Liljegren49e86152014-04-16 19:27:58 +0200166 if (rval == -1) {
167 tst_brkm(TBROK | TERRNO, cleanup_fn,
168 "%s:%d: mkdir(%s,0%o) failed",
169 file, lineno, pathname, mode);
170 }
Garrett Cooper4a3c6582010-12-21 07:07:01 -0800171
172 return (rval);
173}
174
Cyril Hrubis97499c22014-05-07 14:54:22 +0200175int safe_rmdir(const char *file, const int lineno, void (*cleanup_fn) (void),
176 const char *pathname)
177{
178 int rval;
179
180 rval = rmdir(pathname);
181 if (rval == -1) {
182 tst_brkm(TBROK | TERRNO, cleanup_fn,
183 "%s:%d: rmdir(%s) failed",
184 file, lineno, pathname);
185 }
186
187 return (rval);
188}
189
Mats Liljegren49e86152014-04-16 19:27:58 +0200190int safe_munmap(const char *file, const int lineno, void (*cleanup_fn) (void),
191 void *addr, size_t length)
Garrett Cooperca435922010-12-20 12:26:32 -0800192{
193 int rval;
194
195 rval = munmap(addr, length);
Mats Liljegren49e86152014-04-16 19:27:58 +0200196 if (rval == -1) {
197 tst_brkm(TBROK | TERRNO, cleanup_fn,
198 "%s:%d: munmap(%p,%zu) failed",
199 file, lineno, addr, length);
200 }
Garrett Cooperca435922010-12-20 12:26:32 -0800201
Mats Liljegren49e86152014-04-16 19:27:58 +0200202 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800203}
204
Mats Liljegren49e86152014-04-16 19:27:58 +0200205int safe_open(const char *file, const int lineno, void (*cleanup_fn) (void),
206 const char *pathname, int oflags, ...)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800207{
208 va_list ap;
209 int rval;
210 mode_t mode;
211
212 va_start(ap, oflags);
Steven Jackson1750b472016-12-15 22:03:53 +0000213
214 /* Android's NDK's mode_t is smaller than an int, which results in
215 * SIGILL here when passing the mode_t type.
216 */
217 mode = va_arg(ap, int);
218
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800219 va_end(ap);
220
221 rval = open(pathname, oflags, mode);
Mats Liljegren49e86152014-04-16 19:27:58 +0200222 if (rval == -1) {
223 tst_brkm(TBROK | TERRNO, cleanup_fn,
224 "%s:%d: open(%s,%d,0%o) failed",
225 file, lineno, pathname, oflags, mode);
226 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800227
Mats Liljegren49e86152014-04-16 19:27:58 +0200228 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800229}
230
Mats Liljegren49e86152014-04-16 19:27:58 +0200231int safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void),
232 int fildes[2])
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800233{
234 int rval;
235
236 rval = pipe(fildes);
Mats Liljegren49e86152014-04-16 19:27:58 +0200237 if (rval == -1) {
238 tst_brkm(TBROK | TERRNO, cleanup_fn,
239 "%s:%d: pipe({%d,%d}) failed",
240 file, lineno, fildes[0], fildes[1]);
241 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800242
Mats Liljegren49e86152014-04-16 19:27:58 +0200243 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800244}
245
Mats Liljegren49e86152014-04-16 19:27:58 +0200246ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void),
247 char len_strict, int fildes, void *buf, size_t nbyte)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800248{
249 ssize_t rval;
250
251 rval = read(fildes, buf, nbyte);
Mats Liljegren49e86152014-04-16 19:27:58 +0200252 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) {
253 tst_brkm(TBROK | TERRNO, cleanup_fn,
254 "%s:%d: read(%d,%p,%zu) failed, returned %zd",
255 file, lineno, fildes, buf, nbyte, rval);
256 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800257
Mats Liljegren49e86152014-04-16 19:27:58 +0200258 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800259}
260
Mats Liljegren49e86152014-04-16 19:27:58 +0200261int safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void),
262 gid_t egid)
Garrett Cooper400c8362010-12-20 20:02:01 -0800263{
264 int rval;
265
266 rval = setegid(egid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200267 if (rval == -1) {
268 tst_brkm(TBROK | TERRNO, cleanup_fn,
269 "%s:%d: setegid(%u) failed",
270 file, lineno, (unsigned) egid);
271 }
Garrett Cooper400c8362010-12-20 20:02:01 -0800272
Mats Liljegren49e86152014-04-16 19:27:58 +0200273 return rval;
Garrett Cooper400c8362010-12-20 20:02:01 -0800274}
275
Mats Liljegren49e86152014-04-16 19:27:58 +0200276int safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void),
277 uid_t euid)
Garrett Cooper400c8362010-12-20 20:02:01 -0800278{
279 int rval;
280
281 rval = seteuid(euid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200282 if (rval == -1) {
283 tst_brkm(TBROK | TERRNO, cleanup_fn,
284 "%s:%d: seteuid(%u) failed",
285 file, lineno, (unsigned) euid);
286 }
Garrett Cooper400c8362010-12-20 20:02:01 -0800287
Mats Liljegren49e86152014-04-16 19:27:58 +0200288 return rval;
Garrett Cooper400c8362010-12-20 20:02:01 -0800289}
290
Mats Liljegren49e86152014-04-16 19:27:58 +0200291int safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void),
292 gid_t gid)
Garrett Cooperca435922010-12-20 12:26:32 -0800293{
294 int rval;
295
296 rval = setgid(gid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200297 if (rval == -1) {
298 tst_brkm(TBROK | TERRNO, cleanup_fn,
299 "%s:%d: setgid(%u) failed",
300 file, lineno, (unsigned) gid);
301 }
Garrett Cooperca435922010-12-20 12:26:32 -0800302
Mats Liljegren49e86152014-04-16 19:27:58 +0200303 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800304}
305
Mats Liljegren49e86152014-04-16 19:27:58 +0200306int safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void),
307 uid_t uid)
Garrett Cooperca435922010-12-20 12:26:32 -0800308{
309 int rval;
310
311 rval = setuid(uid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200312 if (rval == -1) {
313 tst_brkm(TBROK | TERRNO, cleanup_fn,
314 "%s:%d: setuid(%u) failed",
315 file, lineno, (unsigned) uid);
316 }
Garrett Cooperca435922010-12-20 12:26:32 -0800317
Mats Liljegren49e86152014-04-16 19:27:58 +0200318 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800319}
320
Zeng Linggang91d67422014-04-25 10:46:32 +0800321int safe_getresuid(const char *file, const int lineno, void (*cleanup_fn)(void),
322 uid_t *ruid, uid_t *euid, uid_t *suid)
323{
324 int rval;
325
326 rval = getresuid(ruid, euid, suid);
327 if (rval == -1) {
328 tst_brkm(TBROK | TERRNO, cleanup_fn,
329 "%s:%d: getresuid(%p, %p, %p) failed",
330 file, lineno, ruid, euid, suid);
331 }
332
333 return rval;
334}
335
336int safe_getresgid(const char *file, const int lineno, void (*cleanup_fn)(void),
337 gid_t *rgid, gid_t *egid, gid_t *sgid)
338{
339 int rval;
340
341 rval = getresgid(rgid, egid, sgid);
342 if (rval == -1) {
343 tst_brkm(TBROK | TERRNO, cleanup_fn,
344 "%s:%d: getresgid(%p, %p, %p) failed",
345 file, lineno, rgid, egid, sgid);
346 }
347
348 return rval;
349}
350
Mats Liljegren49e86152014-04-16 19:27:58 +0200351int safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void),
352 const char *pathname)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800353{
354 int rval;
355
356 rval = unlink(pathname);
Mats Liljegren49e86152014-04-16 19:27:58 +0200357 if (rval == -1) {
358 tst_brkm(TBROK | TERRNO, cleanup_fn,
359 "%s:%d: unlink(%s) failed",
360 file, lineno, pathname);
361 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800362
Mats Liljegren49e86152014-04-16 19:27:58 +0200363 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800364}
365
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200366
367int safe_link(const char *file, const int lineno,
368 void (cleanup_fn)(void), const char *oldpath,
369 const char *newpath)
370{
371 int rval;
372
373 rval = link(oldpath, newpath);
374
375 if (rval == -1) {
376 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200377 "%s:%d: link(%s,%s) failed",
378 file, lineno, oldpath, newpath);
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200379 }
380
381 return rval;
382}
383
Alexey Kodanevf3f4d332016-01-28 13:10:58 +0300384int safe_linkat(const char *file, const int lineno,
385 void (cleanup_fn)(void), int olddirfd, const char *oldpath,
386 int newdirfd, const char *newpath, int flags)
387{
388 int rval;
389
390 rval = linkat(olddirfd, oldpath, newdirfd, newpath, flags);
391
392 if (rval == -1) {
393 tst_brkm(TBROK | TERRNO, cleanup_fn,
394 "%s:%d: linkat(%d,%s,%d,%s,%d) failed",
395 file, lineno, olddirfd, oldpath, newdirfd,
396 newpath, flags);
397 }
398
399 return rval;
400}
401
Alexey Kodanev8bbb1d52016-01-28 14:10:54 +0300402ssize_t safe_readlink(const char *file, const int lineno,
403 void (cleanup_fn)(void), const char *path,
404 char *buf, size_t bufsize)
405{
406 ssize_t rval;
407
408 rval = readlink(path, buf, bufsize);
409
410 if (rval == -1) {
411 tst_brkm(TBROK | TERRNO, cleanup_fn,
412 "%s:%d: readlink(%s,%p,%zu) failed",
413 file, lineno, path, buf, bufsize);
414 }
415
416 return rval;
417}
418
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200419int safe_symlink(const char *file, const int lineno,
420 void (cleanup_fn)(void), const char *oldpath,
421 const char *newpath)
422{
423 int rval;
424
425 rval = symlink(oldpath, newpath);
426
427 if (rval == -1) {
428 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200429 "%s:%d: symlink(%s,%s) failed",
430 file, lineno, oldpath, newpath);
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200431 }
432
433 return rval;
434}
435
Mats Liljegren49e86152014-04-16 19:27:58 +0200436ssize_t safe_write(const char *file, const int lineno, void (cleanup_fn) (void),
437 char len_strict, int fildes, const void *buf, size_t nbyte)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800438{
439 ssize_t rval;
440
441 rval = write(fildes, buf, nbyte);
Guangwen Fengf3f10e02015-07-14 14:47:03 +0800442 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) {
Mats Liljegren49e86152014-04-16 19:27:58 +0200443 tst_brkm(TBROK | TERRNO, cleanup_fn,
444 "%s:%d: write(%d,%p,%zu) failed",
445 file, lineno, fildes, buf, rval);
446 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800447
Mats Liljegren49e86152014-04-16 19:27:58 +0200448 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800449}
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100450
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800451long safe_strtol(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800452 void (cleanup_fn) (void), char *str, long min, long max)
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800453{
454 long rval;
455 char *endptr;
456
457 errno = 0;
458 rval = strtol(str, &endptr, 10);
Mats Liljegren49e86152014-04-16 19:27:58 +0200459
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800460 if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN))
Mats Liljegren49e86152014-04-16 19:27:58 +0200461 || (errno != 0 && rval == 0)) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800462 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200463 "%s:%d: strtol(%s) failed", file, lineno, str);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100464 return rval;
Mats Liljegren49e86152014-04-16 19:27:58 +0200465 }
466
467 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800468 tst_brkm(TBROK, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200469 "%s:%d: strtol(%s): Invalid value", file, lineno, str);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100470 return 0;
Mats Liljegren49e86152014-04-16 19:27:58 +0200471 }
472
473 if (rval > max || rval < min) {
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800474 tst_brkm(TBROK, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200475 "%s:%d: strtol(%s): %ld is out of range %ld - %ld",
476 file, lineno, str, rval, min, max);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100477 return 0;
Mats Liljegren49e86152014-04-16 19:27:58 +0200478 }
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800479
480 return rval;
481}
Zhouping Liu2b73a152012-07-07 23:14:39 +0800482
Wanlong Gao354ebb42012-12-07 10:10:04 +0800483unsigned long safe_strtoul(const char *file, const int lineno,
484 void (cleanup_fn) (void), char *str,
485 unsigned long min, unsigned long max)
Zhouping Liu2b73a152012-07-07 23:14:39 +0800486{
487 unsigned long rval;
488 char *endptr;
489
490 errno = 0;
491 rval = strtoul(str, &endptr, 10);
Mats Liljegren49e86152014-04-16 19:27:58 +0200492
Zhouping Liu2b73a152012-07-07 23:14:39 +0800493 if ((errno == ERANGE && rval == ULONG_MAX)
Mats Liljegren49e86152014-04-16 19:27:58 +0200494 || (errno != 0 && rval == 0)) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800495 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200496 "%s:%d: strtoul(%s) failed", file, lineno, str);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100497 return rval;
Mats Liljegren49e86152014-04-16 19:27:58 +0200498 }
499
500 if (rval > max || rval < min) {
Zhouping Liu2b73a152012-07-07 23:14:39 +0800501 tst_brkm(TBROK, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200502 "%s:%d: strtoul(%s): %lu is out of range %lu - %lu",
503 file, lineno, str, rval, min, max);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100504 return 0;
Mats Liljegren49e86152014-04-16 19:27:58 +0200505 }
506
507 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
Zhouping Liu2b73a152012-07-07 23:14:39 +0800508 tst_brkm(TBROK, cleanup_fn,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800509 "Invalid value: '%s' at %s:%d", str, file, lineno);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100510 return 0;
Mats Liljegren49e86152014-04-16 19:27:58 +0200511 }
Zhouping Liu2b73a152012-07-07 23:14:39 +0800512
513 return rval;
514}
Wanlong Gao3b535a82012-10-18 16:35:14 +0800515
516long safe_sysconf(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800517 void (cleanup_fn) (void), int name)
Wanlong Gao3b535a82012-10-18 16:35:14 +0800518{
519 long rval;
520 errno = 0;
521
522 rval = sysconf(name);
523
524 if (rval == -1) {
Mats Liljegren49e86152014-04-16 19:27:58 +0200525 if (errno) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800526 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200527 "%s:%d: sysconf(%d) failed",
528 file, lineno, name);
529 } else {
530 tst_resm(TINFO, "%s:%d: sysconf(%d): "
531 "queried option is not available"
532 " or there is no definite limit",
533 file, lineno, name);
534 }
Wanlong Gao3b535a82012-10-18 16:35:14 +0800535 }
536
537 return rval;
538}
Zeng Linggang1030c9d2014-01-22 13:58:55 +0800539
Cyril Hrubisc4592352014-03-04 16:41:02 +0100540int safe_chmod(const char *file, const int lineno,
541 void (cleanup_fn)(void), const char *path, mode_t mode)
542{
543 int rval;
544
545 rval = chmod(path, mode);
546
547 if (rval == -1) {
548 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200549 "%s:%d: chmod(%s,0%o) failed",
550 file, lineno, path, mode);
Cyril Hrubisc4592352014-03-04 16:41:02 +0100551 }
552
553 return rval;
554}
555
556int safe_fchmod(const char *file, const int lineno,
557 void (cleanup_fn)(void), int fd, mode_t mode)
558{
559 int rval;
560
561 rval = fchmod(fd, mode);
562
563 if (rval == -1) {
564 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200565 "%s:%d: fchmod(%d,0%o) failed",
566 file, lineno, fd, mode);
Cyril Hrubisc4592352014-03-04 16:41:02 +0100567 }
568
569 return rval;
570}
Cyril Hrubisf3e448f2014-04-24 14:24:49 +0200571
Xing Gu92a14592014-06-13 10:53:17 +0800572int safe_chown(const char *file, const int lineno, void (cleanup_fn)(void),
573 const char *path, uid_t owner, gid_t group)
574{
575 int rval;
576
577 rval = chown(path, owner, group);
578
579 if (rval == -1) {
580 tst_brkm(TBROK | TERRNO, cleanup_fn,
581 "%s:%d: chown(%s,%d,%d) failed",
582 file, lineno, path, owner, group);
583 }
584
585 return rval;
586}
Cyril Hrubis34ff2272014-06-04 15:58:50 +0200587
588int safe_fchown(const char *file, const int lineno, void (cleanup_fn)(void),
589 int fd, uid_t owner, gid_t group)
590{
591 int rval;
592
593 rval = fchown(fd, owner, group);
594
595 if (rval == -1) {
596 tst_brkm(TBROK | TERRNO, cleanup_fn,
597 "%s:%d: fchown(%d,%d,%d) failed",
598 file, lineno, fd, owner, group);
599 }
600
601 return rval;
602}
603
Cyril Hrubisf3e448f2014-04-24 14:24:49 +0200604pid_t safe_wait(const char *file, const int lineno, void (cleanup_fn)(void),
605 int *status)
606{
607 pid_t rval;
608
609 rval = wait(status);
610 if (rval == -1) {
611 tst_brkm(TBROK | TERRNO, cleanup_fn,
612 "%s:%d: wait(%p) failed",
613 file, lineno, status);
614 }
615
616 return rval;
617}
618
619pid_t safe_waitpid(const char *file, const int lineno, void (cleanup_fn)(void),
620 pid_t pid, int *status, int opts)
621{
622 pid_t rval;
623
624 rval = waitpid(pid, status, opts);
625 if (rval == -1) {
626 tst_brkm(TBROK | TERRNO, cleanup_fn,
627 "%s:%d: waitpid(%d,%p,%d) failed",
628 file, lineno, pid, status, opts);
629 }
630
631 return rval;
632}
Zeng Linggang5ff25ef2014-05-06 15:49:42 +0800633
634void *safe_memalign(const char *file, const int lineno,
635 void (*cleanup_fn) (void), size_t alignment, size_t size)
636{
637 void *rval;
638
639 rval = memalign(alignment, size);
640 if (rval == NULL)
641 tst_brkm(TBROK | TERRNO, cleanup_fn, "memalign failed at %s:%d",
642 file, lineno);
643
644 return rval;
645}
Xiaoguang Wang6deba582014-05-16 12:52:53 +0800646
647int safe_kill(const char *file, const int lineno, void (cleanup_fn)(void),
648 pid_t pid, int sig)
649{
650 int rval;
651
652 rval = kill(pid, sig);
653
654 if (rval == -1) {
655 tst_brkm(TBROK | TERRNO, cleanup_fn,
656 "%s:%d: kill(%d,%s) failed",
657 file, lineno, pid, tst_strsig(sig));
658 }
659
660 return rval;
661}
Cyril Hrubis3a150e72014-06-11 11:55:23 +0200662
663int safe_mkfifo(const char *file, const int lineno,
664 void (*cleanup_fn)(void), const char *pathname, mode_t mode)
665{
666 int rval;
667
668 rval = mkfifo(pathname, mode);
669
670 if (rval == -1) {
671 tst_brkm(TBROK | TERRNO, cleanup_fn,
672 "%s:%d: mkfifo(%s, 0%o) failed",
673 file, lineno, pathname, mode);
674 }
675
676 return rval;
677}
Xiaoguang Wangf48552a2014-07-27 17:00:53 +0800678
679int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void),
680 const char *oldpath, const char *newpath)
681{
682 int rval;
683
684 rval = rename(oldpath, newpath);
685
686 if (rval == -1) {
687 tst_brkm(TBROK | TERRNO, cleanup_fn,
688 "%s:%d: rename(%s, %s) failed",
689 file, lineno, oldpath, newpath);
690 }
691
692 return rval;
693}
Matus Marhefka8e9db8d2014-08-29 14:22:11 +0200694
695int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void),
696 const char *source, const char *target,
697 const char *filesystemtype, unsigned long mountflags,
698 const void *data)
699{
700 int rval;
701
702 rval = mount(source, target, filesystemtype, mountflags, data);
703
704 if (rval == -1) {
705 tst_brkm(TBROK | TERRNO, cleanup_fn,
706 "%s:%d: mount(%s, %s, %s, %lu, %p) failed",
707 file, lineno, source, target, filesystemtype,
708 mountflags, data);
709 }
710
711 return rval;
712}
713
714int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void),
715 const char *target)
716{
717 int rval;
718
719 rval = umount(target);
720
721 if (rval == -1) {
722 tst_brkm(TBROK | TERRNO, cleanup_fn,
723 "%s:%d: umount(%s) failed",
724 file, lineno, target);
725 }
726
727 return rval;
728}
Cyril Hrubis9138a012015-02-10 15:44:45 +0100729
730DIR* safe_opendir(const char *file, const int lineno, void (cleanup_fn)(void),
731 const char *name)
732{
733 DIR *rval;
734
735 rval = opendir(name);
736
737 if (!rval) {
738 tst_brkm(TBROK | TERRNO, cleanup_fn,
739 "%s:%d: opendir(%s) failed", file, lineno, name);
740 }
741
742 return rval;
743}
744
745int safe_closedir(const char *file, const int lineno, void (cleanup_fn)(void),
746 DIR *dirp)
747{
748 int rval;
749
750 rval = closedir(dirp);
751
752 if (rval) {
753 tst_brkm(TBROK | TERRNO, cleanup_fn,
754 "%s:%d: closedir(%p) failed", file, lineno, dirp);
755 }
756
757 return rval;
758}
759
760struct dirent *safe_readdir(const char *file, const int lineno, void (cleanup_fn)(void),
761 DIR *dirp)
762{
763 struct dirent *rval;
764 int err = errno;
765
766 errno = 0;
767 rval = readdir(dirp);
768
769 if (!rval && errno) {
770 tst_brkm(TBROK | TERRNO, cleanup_fn,
771 "%s:%d: readdir(%p) failed", file, lineno, dirp);
772 }
773
774 errno = err;
775 return rval;
776}
Cyril Hrubisaf5a4b12016-11-07 13:05:00 +0100777
778int safe_getpriority(const char *file, const int lineno, int which, id_t who)
779{
780 int rval, err = errno;
781
782 errno = 0;
783 rval = getpriority(which, who);
784 if (errno) {
785 tst_brkm(TBROK | TERRNO, NULL,
786 "%s:%d getpriority(%i, %i) failed",
787 file, lineno, which, who);
788 }
789
790 errno = err;
791 return rval;
792}
Dejan Jovicevic10552812016-11-15 13:19:33 +0100793
794int safe_setxattr(const char *file, const int lineno, const char *path,
795 const char *name, const void *value, size_t size, int flags)
796{
797 int rval;
798
799 rval = setxattr(path, name, value, size, flags);
800
801 if (rval) {
802 if (errno == ENOTSUP) {
803 tst_brkm(TCONF, NULL,
804 "%s:%d: no xattr support in fs or mounted "
805 "without user_xattr option", file, lineno);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100806 return rval;
Dejan Jovicevic10552812016-11-15 13:19:33 +0100807 }
808
809 tst_brkm(TBROK | TERRNO, NULL, "%s:%d: setxattr() failed",
810 file, lineno);
811 }
812
813 return rval;
814}
815
816int safe_lsetxattr(const char *file, const int lineno, const char *path,
817 const char *name, const void *value, size_t size, int flags)
818{
819 int rval;
820
821 rval = lsetxattr(path, name, value, size, flags);
822
823 if (rval) {
824 if (errno == ENOTSUP) {
825 tst_brkm(TCONF, NULL,
826 "%s:%d: no xattr support in fs or mounted "
827 "without user_xattr option", file, lineno);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100828 return rval;
Dejan Jovicevic10552812016-11-15 13:19:33 +0100829 }
830
831 tst_brkm(TBROK | TERRNO, NULL, "%s:%d: lsetxattr() failed",
832 file, lineno);
833 }
834
835 return rval;
836}
837
838int safe_fsetxattr(const char *file, const int lineno, int fd, const char *name,
839 const void *value, size_t size, int flags)
840{
841 int rval;
842
843 rval = fsetxattr(fd, name, value, size, flags);
844
845 if (rval) {
846 if (errno == ENOTSUP) {
847 tst_brkm(TCONF, NULL,
848 "%s:%d: no xattr support in fs or mounted "
849 "without user_xattr option", file, lineno);
Cyril Hrubisd101cab2017-02-14 11:48:46 +0100850 return rval;
Dejan Jovicevic10552812016-11-15 13:19:33 +0100851 }
852
853 tst_brkm(TBROK | TERRNO, NULL, "%s:%d: fsetxattr() failed",
854 file, lineno);
855 }
856
857 return rval;
858}