blob: 5f29d3b957420365bf0ac790f2e3fae1ea357236 [file] [log] [blame]
Garrett Cooperdd3f47e2010-12-20 05:40:52 -08001#include <sys/types.h>
Garrett Cooperca435922010-12-20 12:26:32 -08002#include <sys/mman.h>
Caspar Zhang817c7822011-06-30 01:50:33 +08003#include <sys/resource.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -08004#include <sys/stat.h>
Vinson Lee9af0bd72012-02-09 15:05:50 -08005#include <errno.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -08006#include <fcntl.h>
7#include <libgen.h>
Caspar Zhangd6a1f252012-02-09 15:58:28 +08008#include <limits.h>
Garrett Cooperca435922010-12-20 12:26:32 -08009#include <pwd.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080010#include <stdarg.h>
Garrett Cooperca435922010-12-20 12:26:32 -080011#include <stdlib.h>
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080012#include <unistd.h>
13#include "test.h"
Garrett Cooperca435922010-12-20 12:26:32 -080014#include "safe_macros.h"
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080015
Wanlong Gao354ebb42012-12-07 10:10:04 +080016char *safe_basename(const char *file, const int lineno,
17 void (*cleanup_fn) (void), char *path)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080018{
19 char *rval;
20
21 rval = basename(path);
22 if (rval == NULL)
Wanlong Gao354ebb42012-12-07 10:10:04 +080023 tst_brkm(TBROK | TERRNO, cleanup_fn, "basename failed at %s:%d",
24 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080025
26 return (rval);
27}
28
29int
Wanlong Gao354ebb42012-12-07 10:10:04 +080030safe_chdir(const char *file, const int lineno, void (*cleanup_fn) (void),
31 const char *path)
Garrett Cooper4a3c6582010-12-21 07:07:01 -080032{
33 int rval;
34
35 rval = chdir(path);
36 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +080037 tst_brkm(TBROK | TERRNO, cleanup_fn, "chdir failed at %s:%d",
38 file, lineno);
Garrett Cooper4a3c6582010-12-21 07:07:01 -080039
40 return (rval);
41}
42
43int
Wanlong Gao354ebb42012-12-07 10:10:04 +080044safe_close(const char *file, const int lineno, void (*cleanup_fn) (void),
45 int fildes)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080046{
47 int rval;
48
49 rval = close(fildes);
50 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +080051 tst_brkm(TBROK | TERRNO, cleanup_fn, "close failed at %s:%d",
52 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080053
54 return (rval);
55}
56
57int
Wanlong Gao354ebb42012-12-07 10:10:04 +080058safe_creat(const char *file, const int lineno, void (*cleanup_fn) (void),
59 char *pathname, mode_t mode)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080060{
61 int rval;
62
63 rval = creat(pathname, mode);
64 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +080065 tst_brkm(TBROK | TERRNO, cleanup_fn, "pipe failed at %s:%d",
66 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080067
68 return (rval);
69}
70
Wanlong Gao354ebb42012-12-07 10:10:04 +080071char *safe_dirname(const char *file, const int lineno,
72 void (*cleanup_fn) (void), char *path)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080073{
74 char *rval;
75
76 rval = dirname(path);
77 if (rval == NULL)
Wanlong Gao354ebb42012-12-07 10:10:04 +080078 tst_brkm(TBROK | TERRNO, cleanup_fn, "dirname failed at %s:%d",
79 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -080080
81 return (rval);
82}
83
Wanlong Gao354ebb42012-12-07 10:10:04 +080084char *safe_getcwd(const char *file, const int lineno, void (*cleanup_fn) (void),
85 char *buf, size_t size)
Garrett Cooperca435922010-12-20 12:26:32 -080086{
87 char *rval;
88
89 rval = getcwd(buf, size);
90 if (rval == NULL)
Wanlong Gao354ebb42012-12-07 10:10:04 +080091 tst_brkm(TBROK | TERRNO, cleanup_fn, "getcwd failed at %s:%d",
92 file, lineno);
Garrett Cooperca435922010-12-20 12:26:32 -080093
94 return (rval);
95}
96
Wanlong Gao354ebb42012-12-07 10:10:04 +080097struct passwd *safe_getpwnam(const char *file, const int lineno,
98 void (*cleanup_fn) (void), const char *name)
Garrett Cooperca435922010-12-20 12:26:32 -080099{
100 struct passwd *rval;
101
102 rval = getpwnam(name);
103 if (rval == NULL)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800104 tst_brkm(TBROK | TERRNO, cleanup_fn, "getpwnam failed at %s:%d",
105 file, lineno);
Garrett Cooperca435922010-12-20 12:26:32 -0800106
107 return (rval);
108}
109
Caspar Zhang817c7822011-06-30 01:50:33 +0800110int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800111safe_getrusage(const char *file, const int lineno, void (*cleanup_fn) (void),
112 int who, struct rusage *usage)
Caspar Zhang817c7822011-06-30 01:50:33 +0800113{
114 int rval;
115
116 rval = getrusage(who, usage);
117 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800118 tst_brkm(TBROK | TERRNO, cleanup_fn,
119 "getrusage failed at %s:%d", file, lineno);
Caspar Zhang817c7822011-06-30 01:50:33 +0800120
121 return rval;
122}
123
Wanlong Gao354ebb42012-12-07 10:10:04 +0800124void *safe_malloc(const char *file, const int lineno, void (*cleanup_fn) (void),
125 size_t size)
Garrett Cooperca435922010-12-20 12:26:32 -0800126{
127 void *rval;
128
129 rval = malloc(size);
130 if (rval == NULL)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800131 tst_brkm(TBROK | TERRNO, cleanup_fn, "malloc failed at %s:%d",
132 file, lineno);
Garrett Cooperca435922010-12-20 12:26:32 -0800133
134 return (rval);
135}
136
Garrett Cooper4a3c6582010-12-21 07:07:01 -0800137int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800138safe_mkdir(const char *file, const int lineno, void (*cleanup_fn) (void),
139 const char *pathname, mode_t mode)
Garrett Cooper4a3c6582010-12-21 07:07:01 -0800140{
141 int rval;
142
143 rval = mkdir(pathname, mode);
144 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800145 tst_brkm(TBROK | TERRNO, cleanup_fn, "mkdir failed at %s:%d",
146 file, lineno);
Garrett Cooper4a3c6582010-12-21 07:07:01 -0800147
148 return (rval);
149}
150
Wanlong Gao354ebb42012-12-07 10:10:04 +0800151void *safe_mmap(const char *file, const int lineno, void (*cleanup_fn) (void),
152 void *addr, size_t length, int prot, int flags, int fd,
153 off_t offset)
Garrett Cooperca435922010-12-20 12:26:32 -0800154{
155 void *rval;
156
157 rval = mmap(addr, length, prot, flags, fd, offset);
158 if (rval == MAP_FAILED)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800159 tst_brkm(TBROK | TERRNO, cleanup_fn, "mmap failed at %s:%d",
160 file, lineno);
Garrett Cooperca435922010-12-20 12:26:32 -0800161
162 return (rval);
163}
164
165int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800166safe_munmap(const char *file, const int lineno, void (*cleanup_fn) (void),
167 void *addr, size_t length)
Garrett Cooperca435922010-12-20 12:26:32 -0800168{
169 int rval;
170
171 rval = munmap(addr, length);
172 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800173 tst_brkm(TBROK | TERRNO, cleanup_fn, "munmap failed at %s:%d",
174 file, lineno);
Garrett Cooperca435922010-12-20 12:26:32 -0800175
176 return (rval);
177}
178
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800179int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800180safe_open(const char *file, const int lineno, void (*cleanup_fn) (void),
181 const char *pathname, int oflags, ...)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800182{
183 va_list ap;
184 int rval;
185 mode_t mode;
186
187 va_start(ap, oflags);
188 mode = va_arg(ap, mode_t);
189 va_end(ap);
190
191 rval = open(pathname, oflags, mode);
192 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800193 tst_brkm(TBROK | TERRNO, cleanup_fn, "open failed at %s:%d",
194 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800195
196 return (rval);
197}
198
199int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800200safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void),
201 int fildes[2])
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800202{
203 int rval;
204
205 rval = pipe(fildes);
206 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800207 tst_brkm(TBROK | TERRNO, cleanup_fn, "pipe failed at %s:%d",
208 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800209
210 return (rval);
211}
212
213ssize_t
Wanlong Gao354ebb42012-12-07 10:10:04 +0800214safe_read(const char *file, const int lineno, void (*cleanup_fn) (void),
215 char len_strict, int fildes, void *buf, size_t nbyte)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800216{
217 ssize_t rval;
218
219 rval = read(fildes, buf, nbyte);
Garrett Cooperac0d5eb2012-05-20 14:05:35 -0700220 if (rval == -1 || (len_strict && rval != nbyte))
Wanlong Gao354ebb42012-12-07 10:10:04 +0800221 tst_brkm(TBROK | TERRNO, cleanup_fn, "read failed at %s:%d",
222 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800223
224 return (rval);
225}
226
Wanlong Gao354ebb42012-12-07 10:10:04 +0800227int
228safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void),
229 gid_t egid)
Garrett Cooper400c8362010-12-20 20:02:01 -0800230{
231 int rval;
232
233 rval = setegid(egid);
234 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800235 tst_brkm(TBROK | TERRNO, cleanup_fn, "setegid failed at %s:%d",
236 file, lineno);
Garrett Cooper400c8362010-12-20 20:02:01 -0800237
238 return (rval);
239}
240
241int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800242safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void),
243 uid_t euid)
Garrett Cooper400c8362010-12-20 20:02:01 -0800244{
245 int rval;
246
247 rval = seteuid(euid);
248 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800249 tst_brkm(TBROK | TERRNO, cleanup_fn, "seteuid failed at %s:%d",
250 file, lineno);
Garrett Cooper400c8362010-12-20 20:02:01 -0800251
252 return (rval);
253}
254
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800255int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800256safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void),
257 gid_t gid)
Garrett Cooperca435922010-12-20 12:26:32 -0800258{
259 int rval;
260
261 rval = setgid(gid);
262 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800263 tst_brkm(TBROK | TERRNO, cleanup_fn, "setgid failed at %s:%d",
264 file, lineno);
Garrett Cooperca435922010-12-20 12:26:32 -0800265
266 return (rval);
267}
268
269int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800270safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void),
271 uid_t uid)
Garrett Cooperca435922010-12-20 12:26:32 -0800272{
273 int rval;
274
275 rval = setuid(uid);
276 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800277 tst_brkm(TBROK | TERRNO, cleanup_fn, "setuid failed at %s:%d",
278 file, lineno);
Garrett Cooperca435922010-12-20 12:26:32 -0800279
280 return (rval);
281}
282
283int
Wanlong Gao354ebb42012-12-07 10:10:04 +0800284safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void),
285 const char *pathname)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800286{
287 int rval;
288
289 rval = unlink(pathname);
290 if (rval == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800291 tst_brkm(TBROK | TERRNO, cleanup_fn, "unlink failed at %s:%d",
292 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800293
294 return (rval);
295}
296
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200297
298int safe_link(const char *file, const int lineno,
299 void (cleanup_fn)(void), const char *oldpath,
300 const char *newpath)
301{
302 int rval;
303
304 rval = link(oldpath, newpath);
305
306 if (rval == -1) {
307 tst_brkm(TBROK | TERRNO, cleanup_fn,
308 "link(%s, %s) failed at %s:%d",
309 oldpath, newpath, file, lineno);
310 }
311
312 return rval;
313}
314
Cyril Hrubisf095ccb2013-11-27 19:55:59 +0100315off_t safe_lseek(const char *file, const int lineno,
316 void (cleanup_fn)(void), int fd,
317 off_t offset, int whence)
318{
319 off_t rval;
320
321 rval = lseek(fd, offset, whence);
322
323 if (rval == (off_t) -1) {
324 tst_brkm(TBROK | TERRNO, cleanup_fn,
325 "lseek(%i, %li, %i) failed at %s:%d",
326 fd, (long)offset, whence, file, lineno);
327 }
328
329 return rval;
330}
331
Cyril Hrubisaede40b2013-04-15 19:33:23 +0200332int safe_symlink(const char *file, const int lineno,
333 void (cleanup_fn)(void), const char *oldpath,
334 const char *newpath)
335{
336 int rval;
337
338 rval = symlink(oldpath, newpath);
339
340 if (rval == -1) {
341 tst_brkm(TBROK | TERRNO, cleanup_fn,
342 "link(%s, %s) failed at %s:%d",
343 oldpath, newpath, file, lineno);
344 }
345
346 return rval;
347}
348
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800349ssize_t
Wanlong Gao354ebb42012-12-07 10:10:04 +0800350safe_write(const char *file, const int lineno, void (cleanup_fn) (void),
351 char len_strict, int fildes, const void *buf, size_t nbyte)
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800352{
353 ssize_t rval;
354
355 rval = write(fildes, buf, nbyte);
356 if ((len_strict == 0 && rval == -1) || rval != nbyte)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800357 tst_brkm(TBROK | TERRNO, cleanup_fn, "write failed at %s:%d",
358 file, lineno);
Garrett Cooperdd3f47e2010-12-20 05:40:52 -0800359
360 return (rval);
361}
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100362
363int safe_ftruncate(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800364 void (cleanup_fn) (void), int fd, off_t length)
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100365{
366 int rval;
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800367
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100368 rval = ftruncate(fd, length);
369 if (rval == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800370 tst_brkm(TBROK | TERRNO, cleanup_fn,
371 "ftruncate failed at %s:%d", file, lineno);
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100372 }
373
374 return rval;
375}
376
377int safe_truncate(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800378 void (cleanup_fn) (void), const char *path, off_t length)
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100379{
380 int rval;
381
382 rval = truncate(path, length);
383 if (rval == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800384 tst_brkm(TBROK | TERRNO, cleanup_fn, "truncate failed at %s:%d",
385 file, lineno);
Cyril Hrubis3f75fe42011-12-28 15:33:12 +0100386 }
387
388 return rval;
389}
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800390
391long safe_strtol(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800392 void (cleanup_fn) (void), char *str, long min, long max)
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800393{
394 long rval;
395 char *endptr;
396
397 errno = 0;
398 rval = strtol(str, &endptr, 10);
399 if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN))
Wanlong Gao354ebb42012-12-07 10:10:04 +0800400 || (errno != 0 && rval == 0))
401 tst_brkm(TBROK | TERRNO, cleanup_fn,
Caspar Zhangd6a1f252012-02-09 15:58:28 +0800402 "strtol failed at %s:%d", file, lineno);
403 if (rval > max || rval < min)
404 tst_brkm(TBROK, cleanup_fn,
405 "converted value out of range (%ld - %ld) at %s:%d",
406 min, max, file, lineno);
407 if (endptr == str || (*endptr != '\0' && *endptr != '\n'))
408 tst_brkm(TBROK, cleanup_fn,
409 "Invalid value: '%s' at %s:%d", str, file, lineno);
410
411 return rval;
412}
Zhouping Liu2b73a152012-07-07 23:14:39 +0800413
Wanlong Gao354ebb42012-12-07 10:10:04 +0800414unsigned long safe_strtoul(const char *file, const int lineno,
415 void (cleanup_fn) (void), char *str,
416 unsigned long min, unsigned long max)
Zhouping Liu2b73a152012-07-07 23:14:39 +0800417{
418 unsigned long rval;
419 char *endptr;
420
421 errno = 0;
422 rval = strtoul(str, &endptr, 10);
423 if ((errno == ERANGE && rval == ULONG_MAX)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800424 || (errno != 0 && rval == 0))
425 tst_brkm(TBROK | TERRNO, cleanup_fn,
426 "strtol failed at %s:%d", file, lineno);
Zhouping Liu2b73a152012-07-07 23:14:39 +0800427 if (rval > max || rval < min)
428 tst_brkm(TBROK, cleanup_fn,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800429 "converted value out of range (%lu - %lu at %s:%d",
430 min, max, file, lineno);
Zhouping Liu2b73a152012-07-07 23:14:39 +0800431 if (endptr == str || (*endptr != '\0' && *endptr != '\n'))
432 tst_brkm(TBROK, cleanup_fn,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800433 "Invalid value: '%s' at %s:%d", str, file, lineno);
Zhouping Liu2b73a152012-07-07 23:14:39 +0800434
435 return rval;
436}
Wanlong Gao3b535a82012-10-18 16:35:14 +0800437
438long safe_sysconf(const char *file, const int lineno,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800439 void (cleanup_fn) (void), int name)
Wanlong Gao3b535a82012-10-18 16:35:14 +0800440{
441 long rval;
442 errno = 0;
443
444 rval = sysconf(name);
445
446 if (rval == -1) {
447 if (errno == EINVAL)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800448 tst_brkm(TBROK | TERRNO, cleanup_fn,
Wanlong Gao3b535a82012-10-18 16:35:14 +0800449 "sysconf failed at %s:%d", file, lineno);
450 else
451 tst_resm(TINFO, "queried option is not available"
452 " or thers is no definite limit at %s:%d",
453 file, lineno);
454 }
455
456 return rval;
457}
Zeng Linggang1030c9d2014-01-22 13:58:55 +0800458
459int safe_fstat(const char *file, const int lineno,
460 void (cleanup_fn)(void), int fd, struct stat *buf)
461{
462 int rval;
463
464 rval = fstat(fd, buf);
465
466 if (rval == -1) {
467 tst_brkm(TBROK | TERRNO, cleanup_fn,
468 "fstat failed at %s:%d", file, lineno);
469 }
470
471 return rval;
472}