Home | History | Annotate | Download | only in lib
      1 #define _GNU_SOURCE
      2 #include <sys/types.h>
      3 #include <sys/mman.h>
      4 #include <sys/resource.h>
      5 #include <sys/stat.h>
      6 #include <sys/wait.h>
      7 #include <sys/mount.h>
      8 #include <sys/xattr.h>
      9 #include <errno.h>
     10 #include <fcntl.h>
     11 #include <libgen.h>
     12 #include <limits.h>
     13 #include <pwd.h>
     14 #include <stdarg.h>
     15 #include <stdlib.h>
     16 #include <unistd.h>
     17 #include <malloc.h>
     18 #include "test.h"
     19 #include "safe_macros.h"
     20 
     21 char *safe_basename(const char *file, const int lineno,
     22 		    void (*cleanup_fn) (void), char *path)
     23 {
     24 	char *rval;
     25 
     26 	rval = basename(path);
     27 	if (rval == NULL) {
     28 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     29 			 "%s:%d: basename(%s) failed",
     30 			 file, lineno, path);
     31 	}
     32 
     33 	return rval;
     34 }
     35 
     36 int
     37 safe_chdir(const char *file, const int lineno, void (*cleanup_fn) (void),
     38 	   const char *path)
     39 {
     40 	int rval;
     41 
     42 	rval = chdir(path);
     43 	if (rval == -1) {
     44 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     45 			 "%s:%d: chdir(%s) failed",
     46 			 file, lineno, path);
     47 	}
     48 
     49 	return rval;
     50 }
     51 
     52 int
     53 safe_close(const char *file, const int lineno, void (*cleanup_fn) (void),
     54 	   int fildes)
     55 {
     56 	int rval;
     57 
     58 	rval = close(fildes);
     59 	if (rval == -1) {
     60 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     61 			 "%s:%d: close(%d) failed",
     62 			 file, lineno, fildes);
     63 	}
     64 
     65 	return rval;
     66 }
     67 
     68 int
     69 safe_creat(const char *file, const int lineno, void (*cleanup_fn) (void),
     70 	   const char *pathname, mode_t mode)
     71 {
     72 	int rval;
     73 
     74 	rval = creat(pathname, mode);
     75 	if (rval == -1) {
     76 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     77 			 "%s:%d: creat(%s,0%o) failed",
     78 			 file, lineno, pathname, mode);
     79 	}
     80 
     81 	return rval;
     82 }
     83 
     84 char *safe_dirname(const char *file, const int lineno,
     85 		   void (*cleanup_fn) (void), char *path)
     86 {
     87 	char *rval;
     88 
     89 	rval = dirname(path);
     90 	if (rval == NULL) {
     91 		tst_brkm(TBROK | TERRNO, cleanup_fn,
     92 			 "%s:%d: dirname(%s) failed",
     93 			 file, lineno, path);
     94 	}
     95 
     96 	return rval;
     97 }
     98 
     99 char *safe_getcwd(const char *file, const int lineno, void (*cleanup_fn) (void),
    100 		  char *buf, size_t size)
    101 {
    102 	char *rval;
    103 
    104 	rval = getcwd(buf, size);
    105 	if (rval == NULL) {
    106 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    107 			 "%s:%d: getcwd(%p,%zu) failed",
    108 			 file, lineno, buf, size);
    109 	}
    110 
    111 	return rval;
    112 }
    113 
    114 struct passwd *safe_getpwnam(const char *file, const int lineno,
    115 			     void (*cleanup_fn) (void), const char *name)
    116 {
    117 	struct passwd *rval;
    118 
    119 	rval = getpwnam(name);
    120 	if (rval == NULL) {
    121 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    122 			 "%s:%d: getpwnam(%s) failed",
    123 			 file, lineno, name);
    124 	}
    125 
    126 	return rval;
    127 }
    128 
    129 int
    130 safe_getrusage(const char *file, const int lineno, void (*cleanup_fn) (void),
    131 	       int who, struct rusage *usage)
    132 {
    133 	int rval;
    134 
    135 	rval = getrusage(who, usage);
    136 	if (rval == -1) {
    137 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    138 			 "%s:%d: getrusage(%d,%p) failed",
    139 			 file, lineno, who, usage);
    140 	}
    141 
    142 	return rval;
    143 }
    144 
    145 void *safe_malloc(const char *file, const int lineno, void (*cleanup_fn) (void),
    146 		  size_t size)
    147 {
    148 	void *rval;
    149 
    150 	rval = malloc(size);
    151 	if (rval == NULL) {
    152 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    153 			 "%s:%d: malloc(%zu) failed",
    154 			 file, lineno, size);
    155 	}
    156 
    157 	return rval;
    158 }
    159 
    160 int safe_mkdir(const char *file, const int lineno, void (*cleanup_fn) (void),
    161                const char *pathname, mode_t mode)
    162 {
    163 	int rval;
    164 
    165 	rval = mkdir(pathname, mode);
    166 	if (rval == -1) {
    167 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    168 			 "%s:%d: mkdir(%s,0%o) failed",
    169 			 file, lineno, pathname, mode);
    170 	}
    171 
    172 	return (rval);
    173 }
    174 
    175 int 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 
    190 int safe_munmap(const char *file, const int lineno, void (*cleanup_fn) (void),
    191                 void *addr, size_t length)
    192 {
    193 	int rval;
    194 
    195 	rval = munmap(addr, length);
    196 	if (rval == -1) {
    197 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    198 			 "%s:%d: munmap(%p,%zu) failed",
    199 			 file, lineno, addr, length);
    200 	}
    201 
    202 	return rval;
    203 }
    204 
    205 int safe_open(const char *file, const int lineno, void (*cleanup_fn) (void),
    206               const char *pathname, int oflags, ...)
    207 {
    208 	va_list ap;
    209 	int rval;
    210 	mode_t mode;
    211 
    212 	va_start(ap, oflags);
    213 
    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 
    219 	va_end(ap);
    220 
    221 	rval = open(pathname, oflags, mode);
    222 	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 	}
    227 
    228 	return rval;
    229 }
    230 
    231 int safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void),
    232               int fildes[2])
    233 {
    234 	int rval;
    235 
    236 	rval = pipe(fildes);
    237 	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 	}
    242 
    243 	return rval;
    244 }
    245 
    246 ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void),
    247                   char len_strict, int fildes, void *buf, size_t nbyte)
    248 {
    249 	ssize_t rval;
    250 
    251 	rval = read(fildes, buf, nbyte);
    252 	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 	}
    257 
    258 	return rval;
    259 }
    260 
    261 int safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void),
    262                  gid_t egid)
    263 {
    264 	int rval;
    265 
    266 	rval = setegid(egid);
    267 	if (rval == -1) {
    268 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    269 			 "%s:%d: setegid(%u) failed",
    270 			 file, lineno, (unsigned) egid);
    271 	}
    272 
    273 	return rval;
    274 }
    275 
    276 int safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void),
    277                  uid_t euid)
    278 {
    279 	int rval;
    280 
    281 	rval = seteuid(euid);
    282 	if (rval == -1) {
    283 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    284 			 "%s:%d: seteuid(%u) failed",
    285 			 file, lineno, (unsigned) euid);
    286 	}
    287 
    288 	return rval;
    289 }
    290 
    291 int safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void),
    292                 gid_t gid)
    293 {
    294 	int rval;
    295 
    296 	rval = setgid(gid);
    297 	if (rval == -1) {
    298 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    299 			 "%s:%d: setgid(%u) failed",
    300 			 file, lineno, (unsigned) gid);
    301 	}
    302 
    303 	return rval;
    304 }
    305 
    306 int safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void),
    307                 uid_t uid)
    308 {
    309 	int rval;
    310 
    311 	rval = setuid(uid);
    312 	if (rval == -1) {
    313 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    314 			 "%s:%d: setuid(%u) failed",
    315 			 file, lineno, (unsigned) uid);
    316 	}
    317 
    318 	return rval;
    319 }
    320 
    321 int 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 
    336 int 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 
    351 int safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void),
    352                 const char *pathname)
    353 {
    354 	int rval;
    355 
    356 	rval = unlink(pathname);
    357 	if (rval == -1) {
    358 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    359 			 "%s:%d: unlink(%s) failed",
    360 			 file, lineno, pathname);
    361 	}
    362 
    363 	return rval;
    364 }
    365 
    366 
    367 int 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,
    377 		         "%s:%d: link(%s,%s) failed",
    378 			 file, lineno, oldpath, newpath);
    379 	}
    380 
    381 	return rval;
    382 }
    383 
    384 int 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 
    402 ssize_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 	} else {
    415 		/* readlink does not append a NUL byte to the buffer.
    416 		 * Add it now. */
    417 		if ((size_t) rval < bufsize)
    418 			buf[rval] = '\0';
    419 		else
    420 			buf[bufsize-1] = '\0';
    421 	}
    422 
    423 	return rval;
    424 }
    425 
    426 int safe_symlink(const char *file, const int lineno,
    427                  void (cleanup_fn)(void), const char *oldpath,
    428                  const char *newpath)
    429 {
    430 	int rval;
    431 
    432 	rval = symlink(oldpath, newpath);
    433 
    434 	if (rval == -1) {
    435 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    436 		         "%s:%d: symlink(%s,%s) failed",
    437 			 file, lineno, oldpath, newpath);
    438 	}
    439 
    440 	return rval;
    441 }
    442 
    443 ssize_t safe_write(const char *file, const int lineno, void (cleanup_fn) (void),
    444                    char len_strict, int fildes, const void *buf, size_t nbyte)
    445 {
    446 	ssize_t rval;
    447 
    448 	rval = write(fildes, buf, nbyte);
    449 	if (rval == -1 || (len_strict && (size_t)rval != nbyte)) {
    450 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    451 			 "%s:%d: write(%d,%p,%zu) failed",
    452 		         file, lineno, fildes, buf, rval);
    453 	}
    454 
    455 	return rval;
    456 }
    457 
    458 long safe_strtol(const char *file, const int lineno,
    459 		 void (cleanup_fn) (void), char *str, long min, long max)
    460 {
    461 	long rval;
    462 	char *endptr;
    463 
    464 	errno = 0;
    465 	rval = strtol(str, &endptr, 10);
    466 
    467 	if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN))
    468 	    || (errno != 0 && rval == 0)) {
    469 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    470 			 "%s:%d: strtol(%s) failed", file, lineno, str);
    471 		return rval;
    472 	}
    473 
    474 	if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
    475 		tst_brkm(TBROK, cleanup_fn,
    476 			 "%s:%d: strtol(%s): Invalid value", file, lineno, str);
    477 		return 0;
    478 	}
    479 
    480 	if (rval > max || rval < min) {
    481 		tst_brkm(TBROK, cleanup_fn,
    482 			 "%s:%d: strtol(%s): %ld is out of range %ld - %ld",
    483 			 file, lineno, str, rval, min, max);
    484 		return 0;
    485 	}
    486 
    487 	return rval;
    488 }
    489 
    490 unsigned long safe_strtoul(const char *file, const int lineno,
    491 			   void (cleanup_fn) (void), char *str,
    492 			   unsigned long min, unsigned long max)
    493 {
    494 	unsigned long rval;
    495 	char *endptr;
    496 
    497 	errno = 0;
    498 	rval = strtoul(str, &endptr, 10);
    499 
    500 	if ((errno == ERANGE && rval == ULONG_MAX)
    501 	    || (errno != 0 && rval == 0)) {
    502 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    503 			 "%s:%d: strtoul(%s) failed", file, lineno, str);
    504 		return rval;
    505 	}
    506 
    507 	if (rval > max || rval < min) {
    508 		tst_brkm(TBROK, cleanup_fn,
    509 			 "%s:%d: strtoul(%s): %lu is out of range %lu - %lu",
    510 			 file, lineno, str, rval, min, max);
    511 		return 0;
    512 	}
    513 
    514 	if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
    515 		tst_brkm(TBROK, cleanup_fn,
    516 			 "Invalid value: '%s' at %s:%d", str, file, lineno);
    517 		return 0;
    518 	}
    519 
    520 	return rval;
    521 }
    522 
    523 long safe_sysconf(const char *file, const int lineno,
    524 		  void (cleanup_fn) (void), int name)
    525 {
    526 	long rval;
    527 	errno = 0;
    528 
    529 	rval = sysconf(name);
    530 
    531 	if (rval == -1) {
    532 		if (errno) {
    533 			tst_brkm(TBROK | TERRNO, cleanup_fn,
    534 				 "%s:%d: sysconf(%d) failed",
    535 				 file, lineno, name);
    536 		} else {
    537 			tst_resm(TINFO, "%s:%d: sysconf(%d): "
    538 				 "queried option is not available"
    539 				 " or there is no definite limit",
    540 				 file, lineno, name);
    541 		}
    542 	}
    543 
    544 	return rval;
    545 }
    546 
    547 int safe_chmod(const char *file, const int lineno,
    548                void (cleanup_fn)(void), const char *path, mode_t mode)
    549 {
    550 	int rval;
    551 
    552 	rval = chmod(path, mode);
    553 
    554 	if (rval == -1) {
    555 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    556 			 "%s:%d: chmod(%s,0%o) failed",
    557 			 file, lineno, path, mode);
    558 	}
    559 
    560 	return rval;
    561 }
    562 
    563 int safe_fchmod(const char *file, const int lineno,
    564                 void (cleanup_fn)(void), int fd, mode_t mode)
    565 {
    566 	int rval;
    567 
    568 	rval = fchmod(fd, mode);
    569 
    570 	if (rval == -1) {
    571 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    572 			 "%s:%d: fchmod(%d,0%o) failed",
    573 			 file, lineno, fd, mode);
    574 	}
    575 
    576 	return rval;
    577 }
    578 
    579 int safe_chown(const char *file, const int lineno, void (cleanup_fn)(void),
    580 			const char *path, uid_t owner, gid_t group)
    581 {
    582 	int rval;
    583 
    584 	rval = chown(path, owner, group);
    585 
    586 	if (rval == -1) {
    587 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    588 			"%s:%d: chown(%s,%d,%d) failed",
    589 			file, lineno, path, owner, group);
    590 	}
    591 
    592 	return rval;
    593 }
    594 
    595 int safe_fchown(const char *file, const int lineno, void (cleanup_fn)(void),
    596                 int fd, uid_t owner, gid_t group)
    597 {
    598 	int rval;
    599 
    600 	rval = fchown(fd, owner, group);
    601 
    602 	if (rval == -1) {
    603 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    604 		         "%s:%d: fchown(%d,%d,%d) failed",
    605 			 file, lineno, fd, owner, group);
    606 	}
    607 
    608 	return rval;
    609 }
    610 
    611 pid_t safe_wait(const char *file, const int lineno, void (cleanup_fn)(void),
    612                 int *status)
    613 {
    614 	pid_t rval;
    615 
    616 	rval = wait(status);
    617 	if (rval == -1) {
    618 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    619 			 "%s:%d: wait(%p) failed",
    620 			 file, lineno, status);
    621 	}
    622 
    623 	return rval;
    624 }
    625 
    626 pid_t safe_waitpid(const char *file, const int lineno, void (cleanup_fn)(void),
    627                    pid_t pid, int *status, int opts)
    628 {
    629 	pid_t rval;
    630 
    631 	rval = waitpid(pid, status, opts);
    632 	if (rval == -1) {
    633 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    634 			 "%s:%d: waitpid(%d,%p,%d) failed",
    635 			 file, lineno, pid, status, opts);
    636 	}
    637 
    638 	return rval;
    639 }
    640 
    641 void *safe_memalign(const char *file, const int lineno,
    642 		    void (*cleanup_fn) (void), size_t alignment, size_t size)
    643 {
    644 	void *rval;
    645 
    646 	rval = memalign(alignment, size);
    647 	if (rval == NULL)
    648 		tst_brkm(TBROK | TERRNO, cleanup_fn, "memalign failed at %s:%d",
    649 			 file, lineno);
    650 
    651 	return rval;
    652 }
    653 
    654 int safe_kill(const char *file, const int lineno, void (cleanup_fn)(void),
    655 	      pid_t pid, int sig)
    656 {
    657 	int rval;
    658 
    659 	rval = kill(pid, sig);
    660 
    661 	if (rval == -1) {
    662 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    663 			 "%s:%d: kill(%d,%s) failed",
    664 			 file, lineno, pid, tst_strsig(sig));
    665 	}
    666 
    667 	return rval;
    668 }
    669 
    670 int safe_mkfifo(const char *file, const int lineno,
    671                 void (*cleanup_fn)(void), const char *pathname, mode_t mode)
    672 {
    673 	int rval;
    674 
    675 	rval = mkfifo(pathname, mode);
    676 
    677 	if (rval == -1) {
    678 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    679 		         "%s:%d: mkfifo(%s, 0%o) failed",
    680 			 file, lineno, pathname, mode);
    681 	}
    682 
    683 	return rval;
    684 }
    685 
    686 int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void),
    687 		const char *oldpath, const char *newpath)
    688 {
    689 	int rval;
    690 
    691 	rval = rename(oldpath, newpath);
    692 
    693 	if (rval == -1) {
    694 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    695 			 "%s:%d: rename(%s, %s) failed",
    696 			 file, lineno, oldpath, newpath);
    697 	}
    698 
    699 	return rval;
    700 }
    701 
    702 struct fuse_fs_type {
    703 	char const *fs_type;
    704 	int fallback;
    705 } fuse_fs_types[] = {
    706 	{ "exfat", 1 },
    707 	{ "ntfs", 0 },
    708 };
    709 
    710 static struct fuse_fs_type* find_fuse_fs_type(const char *fs_type)
    711 {
    712 	unsigned int i;
    713 
    714 	if (!fs_type)
    715 		return 0;
    716 
    717 	for (i = 0; i < ARRAY_SIZE(fuse_fs_types); i++) {
    718 		if (!strcmp(fuse_fs_types[i].fs_type, fs_type))
    719 			return &fuse_fs_types[i];
    720 	}
    721 
    722 	return NULL;
    723 }
    724 
    725 int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void),
    726 	       const char *source, const char *target,
    727 	       const char *filesystemtype, unsigned long mountflags,
    728 	       const void *data)
    729 {
    730 	int rval;
    731 	struct fuse_fs_type *fuse_fs_type = find_fuse_fs_type(filesystemtype);
    732 
    733 	/*
    734 	 * The FUSE filesystem executes mount.fuse helper, which tries to
    735 	 * execute corresponding binary name which is encoded at the start of
    736 	 * the source string and separated by # from the device name.
    737          *
    738 	 * The mount helpers are called mount.$fs_type.
    739 	 */
    740 	if (fuse_fs_type) {
    741 		char buf[1024];
    742 
    743 		tst_resm(TINFO, "Trying FUSE...");
    744 		snprintf(buf, sizeof(buf), "mount.%s '%s' '%s'",
    745 			 filesystemtype, source, target);
    746 
    747 		rval = tst_system(buf);
    748 		if (WIFEXITED(rval) && WEXITSTATUS(rval) == 0)
    749 			return 0;
    750 
    751 		if (fuse_fs_type->fallback) {
    752 			tst_resm(TINFO,
    753 				 "mount.%s failed with %i, falling back to mount()",
    754 				 filesystemtype, rval);
    755 		} else {
    756 			tst_brkm(TBROK, cleanup_fn, "mount.%s failed with %i",
    757 				 filesystemtype, rval);
    758 			return -1;
    759 		}
    760 	}
    761 
    762 	rval = mount(source, target, filesystemtype, mountflags, data);
    763 	if (rval == -1) {
    764 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    765 			 "%s:%d: mount(%s, %s, %s, %lu, %p) failed",
    766 			 file, lineno, source, target, filesystemtype,
    767 			 mountflags, data);
    768 	}
    769 
    770 	return rval;
    771 }
    772 
    773 int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void),
    774 		const char *target)
    775 {
    776 	int rval;
    777 
    778 	rval = umount(target);
    779 
    780 	if (rval == -1) {
    781 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    782 			 "%s:%d: umount(%s) failed",
    783 			 file, lineno, target);
    784 	}
    785 
    786 	return rval;
    787 }
    788 
    789 DIR* safe_opendir(const char *file, const int lineno, void (cleanup_fn)(void),
    790                   const char *name)
    791 {
    792 	DIR *rval;
    793 
    794 	rval = opendir(name);
    795 
    796 	if (!rval) {
    797 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    798 		         "%s:%d: opendir(%s) failed", file, lineno, name);
    799 	}
    800 
    801 	return rval;
    802 }
    803 
    804 int safe_closedir(const char *file, const int lineno, void (cleanup_fn)(void),
    805                   DIR *dirp)
    806 {
    807 	int rval;
    808 
    809 	rval = closedir(dirp);
    810 
    811 	if (rval) {
    812 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    813 		         "%s:%d: closedir(%p) failed", file, lineno, dirp);
    814 	}
    815 
    816 	return rval;
    817 }
    818 
    819 struct dirent *safe_readdir(const char *file, const int lineno, void (cleanup_fn)(void),
    820                             DIR *dirp)
    821 {
    822 	struct dirent *rval;
    823 	int err = errno;
    824 
    825 	errno = 0;
    826 	rval = readdir(dirp);
    827 
    828 	if (!rval && errno) {
    829 		tst_brkm(TBROK | TERRNO, cleanup_fn,
    830 		         "%s:%d: readdir(%p) failed", file, lineno, dirp);
    831 	}
    832 
    833 	errno = err;
    834 	return rval;
    835 }
    836 
    837 int safe_getpriority(const char *file, const int lineno, int which, id_t who)
    838 {
    839 	int rval, err = errno;
    840 
    841 	errno = 0;
    842 	rval = getpriority(which, who);
    843 	if (errno) {
    844 		tst_brkm(TBROK | TERRNO, NULL,
    845 		         "%s:%d getpriority(%i, %i) failed",
    846 			 file, lineno, which, who);
    847 	}
    848 
    849 	errno = err;
    850 	return rval;
    851 }
    852 
    853 ssize_t safe_getxattr(const char *file, const int lineno, const char *path,
    854 		      const char *name, void *value, size_t size)
    855 {
    856 	ssize_t rval;
    857 
    858 	rval = getxattr(path, name, value, size);
    859 
    860 	if (rval == -1) {
    861 		if (errno == ENOTSUP) {
    862 			tst_brkm(TCONF, NULL,
    863 				 "%s:%d: no xattr support in fs or mounted "
    864 				 "without user_xattr option", file, lineno);
    865 		}
    866 
    867 		tst_brkm(TBROK | TERRNO, NULL,
    868 			 "%s:%d: getxattr(%s, %s, %p, %zu) failed",
    869 			 file, lineno, path, name, value, size);
    870 	}
    871 
    872 	return rval;
    873 }
    874 
    875 int safe_setxattr(const char *file, const int lineno, const char *path,
    876 		  const char *name, const void *value, size_t size, int flags)
    877 {
    878 	int rval;
    879 
    880 	rval = setxattr(path, name, value, size, flags);
    881 
    882 	if (rval) {
    883 		if (errno == ENOTSUP) {
    884 			tst_brkm(TCONF, NULL,
    885 				 "%s:%d: no xattr support in fs or mounted "
    886 				 "without user_xattr option", file, lineno);
    887 		}
    888 
    889 		tst_brkm(TBROK | TERRNO, NULL,
    890 			 "%s:%d: setxattr(%s, %s, %p, %zu) failed",
    891 			 file, lineno, path, name, value, size);
    892 	}
    893 
    894 	return rval;
    895 }
    896 
    897 int safe_lsetxattr(const char *file, const int lineno, const char *path,
    898 		   const char *name, const void *value, size_t size, int flags)
    899 {
    900 	int rval;
    901 
    902 	rval = lsetxattr(path, name, value, size, flags);
    903 
    904 	if (rval) {
    905 		if (errno == ENOTSUP) {
    906 			tst_brkm(TCONF, NULL,
    907 				 "%s:%d: no xattr support in fs or mounted "
    908 				 "without user_xattr option", file, lineno);
    909 		}
    910 
    911 		tst_brkm(TBROK | TERRNO, NULL,
    912 			 "%s:%d: lsetxattr(%s, %s, %p, %zu, %i) failed",
    913 			 file, lineno, path, name, value, size, flags);
    914 	}
    915 
    916 	return rval;
    917 }
    918 
    919 int safe_fsetxattr(const char *file, const int lineno, int fd, const char *name,
    920 		   const void *value, size_t size, int flags)
    921 {
    922 	int rval;
    923 
    924 	rval = fsetxattr(fd, name, value, size, flags);
    925 
    926 	if (rval) {
    927 		if (errno == ENOTSUP) {
    928 			tst_brkm(TCONF, NULL,
    929 				 "%s:%d: no xattr support in fs or mounted "
    930 				 "without user_xattr option", file, lineno);
    931 		}
    932 
    933 		tst_brkm(TBROK | TERRNO, NULL,
    934 			 "%s:%d: fsetxattr(%i, %s, %p, %zu, %i) failed",
    935 			 file, lineno, fd, name, value, size, flags);
    936 	}
    937 
    938 	return rval;
    939 }
    940 
    941 int safe_removexattr(const char *file, const int lineno, const char *path,
    942 		const char *name)
    943 {
    944 	int rval;
    945 
    946 	rval = removexattr(path, name);
    947 
    948 	if (rval) {
    949 		if (errno == ENOTSUP) {
    950 			tst_brkm(TCONF, NULL,
    951 				"%s:%d: no xattr support in fs or mounted "
    952 				"without user_xattr option", file, lineno);
    953 		}
    954 
    955 		tst_brkm(TBROK | TERRNO, NULL,
    956 			 "%s:%d: removexattr(%s, %s) failed",
    957 			 file, lineno, path, name);
    958 	}
    959 
    960 	return rval;
    961 }
    962 
    963 int safe_lremovexattr(const char *file, const int lineno, const char *path,
    964 		const char *name)
    965 {
    966 	int rval;
    967 
    968 	rval = lremovexattr(path, name);
    969 
    970 	if (rval) {
    971 		if (errno == ENOTSUP) {
    972 			tst_brkm(TCONF, NULL,
    973 				"%s:%d: no xattr support in fs or mounted "
    974 				"without user_xattr option", file, lineno);
    975 		}
    976 
    977 		tst_brkm(TBROK | TERRNO, NULL,
    978 			 "%s:%d: lremovexattr(%s, %s) failed",
    979 			 file, lineno, path, name);
    980 	}
    981 
    982 	return rval;
    983 }
    984 
    985 int safe_fremovexattr(const char *file, const int lineno, int fd,
    986 		const char *name)
    987 {
    988 	int rval;
    989 
    990 	rval = fremovexattr(fd, name);
    991 
    992 	if (rval) {
    993 		if (errno == ENOTSUP) {
    994 			tst_brkm(TCONF, NULL,
    995 				"%s:%d: no xattr support in fs or mounted "
    996 				"without user_xattr option", file, lineno);
    997 		}
    998 
    999 		tst_brkm(TBROK | TERRNO, NULL,
   1000 			 "%s:%d: fremovexattr(%i, %s) failed",
   1001 			 file, lineno, fd, name);
   1002 	}
   1003 
   1004 	return rval;
   1005 }
   1006 
   1007 int safe_fsync(const char *file, const int lineno, int fd)
   1008 {
   1009 	int rval;
   1010 
   1011 	rval = fsync(fd);
   1012 
   1013 	if (rval) {
   1014 		tst_brkm(TBROK | TERRNO, NULL,
   1015 			"%s:%d: fsync(%i) failed", file, lineno, fd);
   1016 	}
   1017 
   1018 	return rval;
   1019 }
   1020 
   1021 pid_t safe_setsid(const char *file, const int lineno)
   1022 {
   1023 	pid_t rval;
   1024 
   1025 	rval = setsid();
   1026 	if (rval == -1) {
   1027 		tst_brkm(TBROK | TERRNO, NULL,
   1028 			 "%s:%d: setsid() failed", file, lineno);
   1029 	}
   1030 
   1031 	return rval;
   1032 }
   1033 
   1034 int safe_mknod(const char *file, const int lineno, const char *pathname,
   1035 	mode_t mode, dev_t dev)
   1036 {
   1037 	int rval;
   1038 
   1039 	rval = mknod(pathname, mode, dev);
   1040 	if (rval == -1) {
   1041 		tst_brkm(TBROK | TERRNO, NULL,
   1042 			 "%s:%d: mknod() failed", file, lineno);
   1043 	}
   1044 
   1045 	return rval;
   1046 }
   1047 
   1048 int safe_mlock(const char *file, const int lineno, const void *addr,
   1049 	size_t len)
   1050 {
   1051 	int rval;
   1052 
   1053 	rval = mlock(addr, len);
   1054 	if (rval == -1) {
   1055 		tst_brkm(TBROK | TERRNO, NULL,
   1056 			 "%s:%d: mlock() failed", file, lineno);
   1057 	}
   1058 
   1059 	return rval;
   1060 }
   1061 
   1062 int safe_munlock(const char *file, const int lineno, const void *addr,
   1063 	size_t len)
   1064 {
   1065 	int rval;
   1066 
   1067 	rval = munlock(addr, len);
   1068 	if (rval == -1) {
   1069 		tst_brkm(TBROK | TERRNO, NULL,
   1070 			 "%s:%d: munlock() failed", file, lineno);
   1071 	}
   1072 
   1073 	return rval;
   1074 }
   1075 
   1076 int safe_mincore(const char *file, const int lineno, void *start,
   1077 	size_t length, unsigned char *vec)
   1078 {
   1079 	int rval;
   1080 
   1081 	rval = mincore(start, length, vec);
   1082 	if (rval == -1) {
   1083 		tst_brkm(TBROK | TERRNO, NULL,
   1084 			 "%s:%d: mincore() failed", file, lineno);
   1085 	}
   1086 
   1087 	return rval;
   1088 }
   1089