blob: 3cd2c2be5b7c2d60e94c67f1e7f5f6595039c325 [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>
Vinson Lee9af0bd72012-02-09 15:05:50 -08007#include <errno.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -08008#include <fcntl.h>
9#include <libgen.h>
Caspar Zhangd6a1f252012-02-09 15:58:28 +080010#include <limits.h>
Garrett Cooperca435922010-12-20 12:26:32 -080011#include <pwd.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080012#include <stdarg.h>
Garrett Cooperca435922010-12-20 12:26:32 -080013#include <stdlib.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080014#include <unistd.h>
Zeng Linggang5ff25ef2014-05-06 15:49:42 +080015#include <malloc.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080016#include "test.h"
Garrett Cooperca435922010-12-20 12:26:32 -080017#include "safe_macros.h"
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080018
Wanlong Gao354ebb42012-12-07 10:10:04 +080019char *safe_basename(const char *file, const int lineno,
20 void (*cleanup_fn) (void), char *path)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080021{
22 char *rval;
23
24 rval = basename(path);
Mats Liljegren49e86152014-04-16 19:27:58 +020025 if (rval == NULL) {
26 tst_brkm(TBROK | TERRNO, cleanup_fn,
27 "%s:%d: basename(%s) failed",
28 file, lineno, path);
29 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080030
Mats Liljegren49e86152014-04-16 19:27:58 +020031 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080032}
33
34int
Wanlong Gao354ebb42012-12-07 10:10:04 +080035safe_chdir(const char *file, const int lineno, void (*cleanup_fn) (void),
36 const char *path)
Garrett Cooper4a3c6582010-12-21 07:07:01 -080037{
38 int rval;
39
40 rval = chdir(path);
Mats Liljegren49e86152014-04-16 19:27:58 +020041 if (rval == -1) {
42 tst_brkm(TBROK | TERRNO, cleanup_fn,
43 "%s:%d: chdir(%s) failed",
44 file, lineno, path);
45 }
Garrett Cooper4a3c6582010-12-21 07:07:01 -080046
Mats Liljegren49e86152014-04-16 19:27:58 +020047 return rval;
Garrett Cooper4a3c6582010-12-21 07:07:01 -080048}
49
50int
Wanlong Gao354ebb42012-12-07 10:10:04 +080051safe_close(const char *file, const int lineno, void (*cleanup_fn) (void),
52 int fildes)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080053{
54 int rval;
55
56 rval = close(fildes);
Mats Liljegren49e86152014-04-16 19:27:58 +020057 if (rval == -1) {
58 tst_brkm(TBROK | TERRNO, cleanup_fn,
59 "%s:%d: close(%d) failed",
60 file, lineno, fildes);
61 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080062
Mats Liljegren49e86152014-04-16 19:27:58 +020063 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080064}
65
66int
Wanlong Gao354ebb42012-12-07 10:10:04 +080067safe_creat(const char *file, const int lineno, void (*cleanup_fn) (void),
68 char *pathname, mode_t mode)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080069{
70 int rval;
71
72 rval = creat(pathname, mode);
Mats Liljegren49e86152014-04-16 19:27:58 +020073 if (rval == -1) {
74 tst_brkm(TBROK | TERRNO, cleanup_fn,
75 "%s:%d: creat(%s,0%o) failed",
76 file, lineno, pathname, mode);
77 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080078
Mats Liljegren49e86152014-04-16 19:27:58 +020079 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080080}
81
Wanlong Gao354ebb42012-12-07 10:10:04 +080082char *safe_dirname(const char *file, const int lineno,
83 void (*cleanup_fn) (void), char *path)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080084{
85 char *rval;
86
87 rval = dirname(path);
Mats Liljegren49e86152014-04-16 19:27:58 +020088 if (rval == NULL) {
89 tst_brkm(TBROK | TERRNO, cleanup_fn,
90 "%s:%d: dirname(%s) failed",
91 file, lineno, path);
92 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080093
Mats Liljegren49e86152014-04-16 19:27:58 +020094 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080095}
96
Wanlong Gao354ebb42012-12-07 10:10:04 +080097char *safe_getcwd(const char *file, const int lineno, void (*cleanup_fn) (void),
98 char *buf, size_t size)
Garrett Cooperca435922010-12-20 12:26:32 -080099{
100 char *rval;
101
102 rval = getcwd(buf, size);
Mats Liljegren49e86152014-04-16 19:27:58 +0200103 if (rval == NULL) {
104 tst_brkm(TBROK | TERRNO, cleanup_fn,
105 "%s:%d: getcwd(%p,%zu) failed",
106 file, lineno, buf, size);
107 }
Garrett Cooperca435922010-12-20 12:26:32 -0800108
Mats Liljegren49e86152014-04-16 19:27:58 +0200109 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800110}
111
Wanlong Gao354ebb42012-12-07 10:10:04 +0800112struct passwd *safe_getpwnam(const char *file, const int lineno,
113 void (*cleanup_fn) (void), const char *name)
Garrett Cooperca435922010-12-20 12:26:32 -0800114{
115 struct passwd *rval;
116
117 rval = getpwnam(name);
Mats Liljegren49e86152014-04-16 19:27:58 +0200118 if (rval == NULL) {
119 tst_brkm(TBROK | TERRNO, cleanup_fn,
120 "%s:%d: getpwnam(%s) failed",
121 file, lineno, name);
122 }
Garrett Cooperca435922010-12-20 12:26:32 -0800123
Mats Liljegren49e86152014-04-16 19:27:58 +0200124 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800125}
126
Caspar Zhang817c7822011-06-30 01:50:33 +0800127int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800128safe_getrusage(const char *file, const int lineno, void (*cleanup_fn) (void),
129 int who, struct rusage *usage)
Caspar Zhang817c7822011-06-30 01:50:33 +0800130{
131 int rval;
132
133 rval = getrusage(who, usage);
Mats Liljegren49e86152014-04-16 19:27:58 +0200134 if (rval == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800135 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200136 "%s:%d: getrusage(%d,%p) failed",
137 file, lineno, who, usage);
138 }
Caspar Zhang817c7822011-06-30 01:50:33 +0800139
140 return rval;
141}
142
Wanlong Gao354ebb42012-12-07 10:10:04 +0800143void *safe_malloc(const char *file, const int lineno, void (*cleanup_fn) (void),
144 size_t size)
Garrett Cooperca435922010-12-20 12:26:32 -0800145{
146 void *rval;
147
148 rval = malloc(size);
Mats Liljegren49e86152014-04-16 19:27:58 +0200149 if (rval == NULL) {
150 tst_brkm(TBROK | TERRNO, cleanup_fn,
151 "%s:%d: malloc(%zu) failed",
152 file, lineno, size);
153 }
Garrett Cooperca435922010-12-20 12:26:32 -0800154
Mats Liljegren49e86152014-04-16 19:27:58 +0200155 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800156}
157
Mats Liljegren49e86152014-04-16 19:27:58 +0200158int safe_mkdir(const char *file, const int lineno, void (*cleanup_fn) (void),
159 const char *pathname, mode_t mode)
Garrett Cooper4a3c6582010-12-21 07:07:01 -0800160{
161 int rval;
162
163 rval = mkdir(pathname, mode);
Mats Liljegren49e86152014-04-16 19:27:58 +0200164 if (rval == -1) {
165 tst_brkm(TBROK | TERRNO, cleanup_fn,
166 "%s:%d: mkdir(%s,0%o) failed",
167 file, lineno, pathname, mode);
168 }
Garrett Cooper4a3c6582010-12-21 07:07:01 -0800169
170 return (rval);
171}
172
Cyril Hrubis97499c22014-05-07 14:54:22 +0200173int safe_rmdir(const char *file, const int lineno, void (*cleanup_fn) (void),
174 const char *pathname)
175{
176 int rval;
177
178 rval = rmdir(pathname);
179 if (rval == -1) {
180 tst_brkm(TBROK | TERRNO, cleanup_fn,
181 "%s:%d: rmdir(%s) failed",
182 file, lineno, pathname);
183 }
184
185 return (rval);
186}
187
Wanlong Gao354ebb42012-12-07 10:10:04 +0800188void *safe_mmap(const char *file, const int lineno, void (*cleanup_fn) (void),
189 void *addr, size_t length, int prot, int flags, int fd,
190 off_t offset)
Garrett Cooperca435922010-12-20 12:26:32 -0800191{
192 void *rval;
193
194 rval = mmap(addr, length, prot, flags, fd, offset);
Mats Liljegren49e86152014-04-16 19:27:58 +0200195 if (rval == MAP_FAILED) {
196 tst_brkm(TBROK | TERRNO, cleanup_fn,
197 "%s:%d: mmap(%p,%zu,%d,%d,%d,%ld) failed",
198 file, lineno, addr, length, prot, flags, fd,
199 (long) offset);
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_munmap(const char *file, const int lineno, void (*cleanup_fn) (void),
206 void *addr, size_t length)
Garrett Cooperca435922010-12-20 12:26:32 -0800207{
208 int rval;
209
210 rval = munmap(addr, length);
Mats Liljegren49e86152014-04-16 19:27:58 +0200211 if (rval == -1) {
212 tst_brkm(TBROK | TERRNO, cleanup_fn,
213 "%s:%d: munmap(%p,%zu) failed",
214 file, lineno, addr, length);
215 }
Garrett Cooperca435922010-12-20 12:26:32 -0800216
Mats Liljegren49e86152014-04-16 19:27:58 +0200217 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800218}
219
Mats Liljegren49e86152014-04-16 19:27:58 +0200220int safe_open(const char *file, const int lineno, void (*cleanup_fn) (void),
221 const char *pathname, int oflags, ...)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800222{
223 va_list ap;
224 int rval;
225 mode_t mode;
226
227 va_start(ap, oflags);
228 mode = va_arg(ap, mode_t);
229 va_end(ap);
230
231 rval = open(pathname, oflags, mode);
Mats Liljegren49e86152014-04-16 19:27:58 +0200232 if (rval == -1) {
233 tst_brkm(TBROK | TERRNO, cleanup_fn,
234 "%s:%d: open(%s,%d,0%o) failed",
235 file, lineno, pathname, oflags, mode);
236 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800237
Mats Liljegren49e86152014-04-16 19:27:58 +0200238 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800239}
240
Mats Liljegren49e86152014-04-16 19:27:58 +0200241int safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void),
242 int fildes[2])
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800243{
244 int rval;
245
246 rval = pipe(fildes);
Mats Liljegren49e86152014-04-16 19:27:58 +0200247 if (rval == -1) {
248 tst_brkm(TBROK | TERRNO, cleanup_fn,
249 "%s:%d: pipe({%d,%d}) failed",
250 file, lineno, fildes[0], fildes[1]);
251 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800252
Mats Liljegren49e86152014-04-16 19:27:58 +0200253 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800254}
255
Mats Liljegren49e86152014-04-16 19:27:58 +0200256ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void),
257 char len_strict, int fildes, void *buf, size_t nbyte)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800258{
259 ssize_t rval;
260
261 rval = read(fildes, buf, nbyte);
Mats Liljegren49e86152014-04-16 19:27:58 +0200262 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) {
263 tst_brkm(TBROK | TERRNO, cleanup_fn,
264 "%s:%d: read(%d,%p,%zu) failed, returned %zd",
265 file, lineno, fildes, buf, nbyte, rval);
266 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800267
Mats Liljegren49e86152014-04-16 19:27:58 +0200268 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800269}
270
Mats Liljegren49e86152014-04-16 19:27:58 +0200271int safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void),
272 gid_t egid)
Garrett Cooper400c8362010-12-20 20:02:01 -0800273{
274 int rval;
275
276 rval = setegid(egid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200277 if (rval == -1) {
278 tst_brkm(TBROK | TERRNO, cleanup_fn,
279 "%s:%d: setegid(%u) failed",
280 file, lineno, (unsigned) egid);
281 }
Garrett Cooper400c8362010-12-20 20:02:01 -0800282
Mats Liljegren49e86152014-04-16 19:27:58 +0200283 return rval;
Garrett Cooper400c8362010-12-20 20:02:01 -0800284}
285
Mats Liljegren49e86152014-04-16 19:27:58 +0200286int safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void),
287 uid_t euid)
Garrett Cooper400c8362010-12-20 20:02:01 -0800288{
289 int rval;
290
291 rval = seteuid(euid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200292 if (rval == -1) {
293 tst_brkm(TBROK | TERRNO, cleanup_fn,
294 "%s:%d: seteuid(%u) failed",
295 file, lineno, (unsigned) euid);
296 }
Garrett Cooper400c8362010-12-20 20:02:01 -0800297
Mats Liljegren49e86152014-04-16 19:27:58 +0200298 return rval;
Garrett Cooper400c8362010-12-20 20:02:01 -0800299}
300
Mats Liljegren49e86152014-04-16 19:27:58 +0200301int safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void),
302 gid_t gid)
Garrett Cooperca435922010-12-20 12:26:32 -0800303{
304 int rval;
305
306 rval = setgid(gid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200307 if (rval == -1) {
308 tst_brkm(TBROK | TERRNO, cleanup_fn,
309 "%s:%d: setgid(%u) failed",
310 file, lineno, (unsigned) gid);
311 }
Garrett Cooperca435922010-12-20 12:26:32 -0800312
Mats Liljegren49e86152014-04-16 19:27:58 +0200313 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800314}
315
Mats Liljegren49e86152014-04-16 19:27:58 +0200316int safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void),
317 uid_t uid)
Garrett Cooperca435922010-12-20 12:26:32 -0800318{
319 int rval;
320
321 rval = setuid(uid);
Mats Liljegren49e86152014-04-16 19:27:58 +0200322 if (rval == -1) {
323 tst_brkm(TBROK | TERRNO, cleanup_fn,
324 "%s:%d: setuid(%u) failed",
325 file, lineno, (unsigned) uid);
326 }
Garrett Cooperca435922010-12-20 12:26:32 -0800327
Mats Liljegren49e86152014-04-16 19:27:58 +0200328 return rval;
Garrett Cooperca435922010-12-20 12:26:32 -0800329}
330
Zeng Linggang91d67422014-04-25 10:46:32 +0800331int safe_getresuid(const char *file, const int lineno, void (*cleanup_fn)(void),
332 uid_t *ruid, uid_t *euid, uid_t *suid)
333{
334 int rval;
335
336 rval = getresuid(ruid, euid, suid);
337 if (rval == -1) {
338 tst_brkm(TBROK | TERRNO, cleanup_fn,
339 "%s:%d: getresuid(%p, %p, %p) failed",
340 file, lineno, ruid, euid, suid);
341 }
342
343 return rval;
344}
345
346int safe_getresgid(const char *file, const int lineno, void (*cleanup_fn)(void),
347 gid_t *rgid, gid_t *egid, gid_t *sgid)
348{
349 int rval;
350
351 rval = getresgid(rgid, egid, sgid);
352 if (rval == -1) {
353 tst_brkm(TBROK | TERRNO, cleanup_fn,
354 "%s:%d: getresgid(%p, %p, %p) failed",
355 file, lineno, rgid, egid, sgid);
356 }
357
358 return rval;
359}
360
Mats Liljegren49e86152014-04-16 19:27:58 +0200361int safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void),
362 const char *pathname)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800363{
364 int rval;
365
366 rval = unlink(pathname);
Mats Liljegren49e86152014-04-16 19:27:58 +0200367 if (rval == -1) {
368 tst_brkm(TBROK | TERRNO, cleanup_fn,
369 "%s:%d: unlink(%s) failed",
370 file, lineno, pathname);
371 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800372
Mats Liljegren49e86152014-04-16 19:27:58 +0200373 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800374}
375
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200376
377int safe_link(const char *file, const int lineno,
378 void (cleanup_fn)(void), const char *oldpath,
379 const char *newpath)
380{
381 int rval;
382
383 rval = link(oldpath, newpath);
384
385 if (rval == -1) {
386 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200387 "%s:%d: link(%s,%s) failed",
388 file, lineno, oldpath, newpath);
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200389 }
390
391 return rval;
392}
393
Cyril Hrubisf095ccb2013-11-27 19:55:59 +0100394off_t safe_lseek(const char *file, const int lineno,
395 void (cleanup_fn)(void), int fd,
396 off_t offset, int whence)
397{
398 off_t rval;
399
400 rval = lseek(fd, offset, whence);
401
402 if (rval == (off_t) -1) {
403 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200404 "%s:%d: lseek(%d,%ld,%d) failed",
405 file, lineno, fd, (long)offset, whence);
Cyril Hrubisf095ccb2013-11-27 19:55:59 +0100406 }
407
408 return rval;
409}
410
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200411int safe_symlink(const char *file, const int lineno,
412 void (cleanup_fn)(void), const char *oldpath,
413 const char *newpath)
414{
415 int rval;
416
417 rval = symlink(oldpath, newpath);
418
419 if (rval == -1) {
420 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200421 "%s:%d: symlink(%s,%s) failed",
422 file, lineno, oldpath, newpath);
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200423 }
424
425 return rval;
426}
427
Mats Liljegren49e86152014-04-16 19:27:58 +0200428ssize_t safe_write(const char *file, const int lineno, void (cleanup_fn) (void),
429 char len_strict, int fildes, const void *buf, size_t nbyte)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800430{
431 ssize_t rval;
432
433 rval = write(fildes, buf, nbyte);
Mats Liljegren49e86152014-04-16 19:27:58 +0200434 if ((len_strict == 0 && rval == -1) || (size_t)rval != nbyte) {
435 tst_brkm(TBROK | TERRNO, cleanup_fn,
436 "%s:%d: write(%d,%p,%zu) failed",
437 file, lineno, fildes, buf, rval);
438 }
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800439
Mats Liljegren49e86152014-04-16 19:27:58 +0200440 return rval;
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800441}
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100442
443int safe_ftruncate(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800444 void (cleanup_fn) (void), int fd, off_t length)
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100445{
446 int rval;
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800447
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100448 rval = ftruncate(fd, length);
449 if (rval == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800450 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200451 "%s:%d: ftruncate(%d,%ld) failed",
452 file, lineno, fd, (long)length);
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100453 }
454
455 return rval;
456}
457
458int safe_truncate(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800459 void (cleanup_fn) (void), const char *path, off_t length)
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100460{
461 int rval;
462
463 rval = truncate(path, length);
464 if (rval == -1) {
Mats Liljegren49e86152014-04-16 19:27:58 +0200465 tst_brkm(TBROK | TERRNO, cleanup_fn,
466 "%s:%d: truncate(%s,%ld) failed",
467 file, lineno, path, (long)length);
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100468 }
469
470 return rval;
471}
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800472
473long safe_strtol(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800474 void (cleanup_fn) (void), char *str, long min, long max)
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800475{
476 long rval;
477 char *endptr;
478
479 errno = 0;
480 rval = strtol(str, &endptr, 10);
Mats Liljegren49e86152014-04-16 19:27:58 +0200481
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800482 if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN))
Mats Liljegren49e86152014-04-16 19:27:58 +0200483 || (errno != 0 && rval == 0)) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800484 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200485 "%s:%d: strtol(%s) failed", file, lineno, str);
486 }
487
488 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800489 tst_brkm(TBROK, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200490 "%s:%d: strtol(%s): Invalid value", file, lineno, str);
491 }
492
493 if (rval > max || rval < min) {
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800494 tst_brkm(TBROK, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200495 "%s:%d: strtol(%s): %ld is out of range %ld - %ld",
496 file, lineno, str, rval, min, max);
497 }
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800498
499 return rval;
500}
Zhouping Liu2b73a152012-07-07 23:14:39 +0800501
Wanlong Gao354ebb42012-12-07 10:10:04 +0800502unsigned long safe_strtoul(const char *file, const int lineno,
503 void (cleanup_fn) (void), char *str,
504 unsigned long min, unsigned long max)
Zhouping Liu2b73a152012-07-07 23:14:39 +0800505{
506 unsigned long rval;
507 char *endptr;
508
509 errno = 0;
510 rval = strtoul(str, &endptr, 10);
Mats Liljegren49e86152014-04-16 19:27:58 +0200511
Zhouping Liu2b73a152012-07-07 23:14:39 +0800512 if ((errno == ERANGE && rval == ULONG_MAX)
Mats Liljegren49e86152014-04-16 19:27:58 +0200513 || (errno != 0 && rval == 0)) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800514 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200515 "%s:%d: strtoul(%s) failed", file, lineno, str);
516 }
517
518 if (rval > max || rval < min) {
Zhouping Liu2b73a152012-07-07 23:14:39 +0800519 tst_brkm(TBROK, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200520 "%s:%d: strtoul(%s): %lu is out of range %lu - %lu",
521 file, lineno, str, rval, min, max);
522 }
523
524 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
Zhouping Liu2b73a152012-07-07 23:14:39 +0800525 tst_brkm(TBROK, cleanup_fn,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800526 "Invalid value: '%s' at %s:%d", str, file, lineno);
Mats Liljegren49e86152014-04-16 19:27:58 +0200527 }
Zhouping Liu2b73a152012-07-07 23:14:39 +0800528
529 return rval;
530}
Wanlong Gao3b535a82012-10-18 16:35:14 +0800531
532long safe_sysconf(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800533 void (cleanup_fn) (void), int name)
Wanlong Gao3b535a82012-10-18 16:35:14 +0800534{
535 long rval;
536 errno = 0;
537
538 rval = sysconf(name);
539
540 if (rval == -1) {
Mats Liljegren49e86152014-04-16 19:27:58 +0200541 if (errno) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800542 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200543 "%s:%d: sysconf(%d) failed",
544 file, lineno, name);
545 } else {
546 tst_resm(TINFO, "%s:%d: sysconf(%d): "
547 "queried option is not available"
548 " or there is no definite limit",
549 file, lineno, name);
550 }
Wanlong Gao3b535a82012-10-18 16:35:14 +0800551 }
552
553 return rval;
554}
Zeng Linggang1030c9d2014-01-22 13:58:55 +0800555
Cyril Hrubis7ee63272014-02-25 16:38:24 +0100556int safe_stat(const char *file, const int lineno,
557 void (cleanup_fn)(void), const char *path, struct stat *buf)
558{
559 int rval;
560
561 rval = stat(path, buf);
562
563 if (rval == -1) {
564 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200565 "%s:%d: stat(%s,%p) failed", file, lineno, path, buf);
Cyril Hrubis7ee63272014-02-25 16:38:24 +0100566 }
567
568 return rval;
569}
570
Zeng Linggang1030c9d2014-01-22 13:58:55 +0800571int safe_fstat(const char *file, const int lineno,
572 void (cleanup_fn)(void), int fd, struct stat *buf)
573{
574 int rval;
575
576 rval = fstat(fd, buf);
577
578 if (rval == -1) {
579 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200580 "%s:%d: fstat(%d,%p) failed", file, lineno, fd, buf);
Cyril Hrubis7ee63272014-02-25 16:38:24 +0100581 }
582
583 return rval;
584}
585
586int safe_lstat(const char *file, const int lineno,
587 void (cleanup_fn)(void), const char *path, struct stat *buf)
588{
589 int rval;
590
591 rval = lstat(path, buf);
592
593 if (rval == -1) {
594 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200595 "%s:%d: lstat(%s,%p) failed", file, lineno, path, buf);
Zeng Linggang1030c9d2014-01-22 13:58:55 +0800596 }
597
598 return rval;
599}
Zeng Linggangef9aac62014-03-03 19:22:55 +0800600
601int safe_getrlimit(const char *file, const int lineno,
602 void (cleanup_fn)(void), int resource, struct rlimit *rlim)
603{
604 int rval;
605
606 rval = getrlimit(resource, rlim);
607
608 if (rval == -1) {
609 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200610 "%s:%d: getrlimit(%d,%p) failed",
611 file, lineno, resource, rlim);
Zeng Linggangef9aac62014-03-03 19:22:55 +0800612 }
613
614 return rval;
615}
616
617int safe_setrlimit(const char *file, const int lineno, void (cleanup_fn)(void),
618 int resource, const struct rlimit *rlim)
619{
620 int rval;
621
622 rval = setrlimit(resource, rlim);
623
624 if (rval == -1) {
625 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200626 "%s:%d: setrlimit(%d,%p) failed",
627 file, lineno, resource, rlim);
Zeng Linggangef9aac62014-03-03 19:22:55 +0800628 }
629
630 return rval;
631}
Cyril Hrubisc4592352014-03-04 16:41:02 +0100632
633int safe_chmod(const char *file, const int lineno,
634 void (cleanup_fn)(void), const char *path, mode_t mode)
635{
636 int rval;
637
638 rval = chmod(path, mode);
639
640 if (rval == -1) {
641 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200642 "%s:%d: chmod(%s,0%o) failed",
643 file, lineno, path, mode);
Cyril Hrubisc4592352014-03-04 16:41:02 +0100644 }
645
646 return rval;
647}
648
649int safe_fchmod(const char *file, const int lineno,
650 void (cleanup_fn)(void), int fd, mode_t mode)
651{
652 int rval;
653
654 rval = fchmod(fd, mode);
655
656 if (rval == -1) {
657 tst_brkm(TBROK | TERRNO, cleanup_fn,
Mats Liljegren49e86152014-04-16 19:27:58 +0200658 "%s:%d: fchmod(%d,0%o) failed",
659 file, lineno, fd, mode);
Cyril Hrubisc4592352014-03-04 16:41:02 +0100660 }
661
662 return rval;
663}
Cyril Hrubisf3e448f2014-04-24 14:24:49 +0200664
665pid_t safe_wait(const char *file, const int lineno, void (cleanup_fn)(void),
666 int *status)
667{
668 pid_t rval;
669
670 rval = wait(status);
671 if (rval == -1) {
672 tst_brkm(TBROK | TERRNO, cleanup_fn,
673 "%s:%d: wait(%p) failed",
674 file, lineno, status);
675 }
676
677 return rval;
678}
679
680pid_t safe_waitpid(const char *file, const int lineno, void (cleanup_fn)(void),
681 pid_t pid, int *status, int opts)
682{
683 pid_t rval;
684
685 rval = waitpid(pid, status, opts);
686 if (rval == -1) {
687 tst_brkm(TBROK | TERRNO, cleanup_fn,
688 "%s:%d: waitpid(%d,%p,%d) failed",
689 file, lineno, pid, status, opts);
690 }
691
692 return rval;
693}
Zeng Linggang5ff25ef2014-05-06 15:49:42 +0800694
695void *safe_memalign(const char *file, const int lineno,
696 void (*cleanup_fn) (void), size_t alignment, size_t size)
697{
698 void *rval;
699
700 rval = memalign(alignment, size);
701 if (rval == NULL)
702 tst_brkm(TBROK | TERRNO, cleanup_fn, "memalign failed at %s:%d",
703 file, lineno);
704
705 return rval;
706}