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 <errno.h> 9 #include <fcntl.h> 10 #include <libgen.h> 11 #include <limits.h> 12 #include <pwd.h> 13 #include <stdarg.h> 14 #include <stdlib.h> 15 #include <unistd.h> 16 #include <malloc.h> 17 #include "test.h" 18 #include "safe_macros.h" 19 20 char *safe_basename(const char *file, const int lineno, 21 void (*cleanup_fn) (void), char *path) 22 { 23 char *rval; 24 25 rval = basename(path); 26 if (rval == NULL) { 27 tst_brkm(TBROK | TERRNO, cleanup_fn, 28 "%s:%d: basename(%s) failed", 29 file, lineno, path); 30 } 31 32 return rval; 33 } 34 35 int 36 safe_chdir(const char *file, const int lineno, void (*cleanup_fn) (void), 37 const char *path) 38 { 39 int rval; 40 41 rval = chdir(path); 42 if (rval == -1) { 43 tst_brkm(TBROK | TERRNO, cleanup_fn, 44 "%s:%d: chdir(%s) failed", 45 file, lineno, path); 46 } 47 48 return rval; 49 } 50 51 int 52 safe_close(const char *file, const int lineno, void (*cleanup_fn) (void), 53 int fildes) 54 { 55 int rval; 56 57 rval = close(fildes); 58 if (rval == -1) { 59 tst_brkm(TBROK | TERRNO, cleanup_fn, 60 "%s:%d: close(%d) failed", 61 file, lineno, fildes); 62 } 63 64 return rval; 65 } 66 67 int 68 safe_creat(const char *file, const int lineno, void (*cleanup_fn) (void), 69 const char *pathname, mode_t mode) 70 { 71 int rval; 72 73 rval = creat(pathname, mode); 74 if (rval == -1) { 75 tst_brkm(TBROK | TERRNO, cleanup_fn, 76 "%s:%d: creat(%s,0%o) failed", 77 file, lineno, pathname, mode); 78 } 79 80 return rval; 81 } 82 83 char *safe_dirname(const char *file, const int lineno, 84 void (*cleanup_fn) (void), char *path) 85 { 86 char *rval; 87 88 rval = dirname(path); 89 if (rval == NULL) { 90 tst_brkm(TBROK | TERRNO, cleanup_fn, 91 "%s:%d: dirname(%s) failed", 92 file, lineno, path); 93 } 94 95 return rval; 96 } 97 98 char *safe_getcwd(const char *file, const int lineno, void (*cleanup_fn) (void), 99 char *buf, size_t size) 100 { 101 char *rval; 102 103 rval = getcwd(buf, size); 104 if (rval == NULL) { 105 tst_brkm(TBROK | TERRNO, cleanup_fn, 106 "%s:%d: getcwd(%p,%zu) failed", 107 file, lineno, buf, size); 108 } 109 110 return rval; 111 } 112 113 struct passwd *safe_getpwnam(const char *file, const int lineno, 114 void (*cleanup_fn) (void), const char *name) 115 { 116 struct passwd *rval; 117 118 rval = getpwnam(name); 119 if (rval == NULL) { 120 tst_brkm(TBROK | TERRNO, cleanup_fn, 121 "%s:%d: getpwnam(%s) failed", 122 file, lineno, name); 123 } 124 125 return rval; 126 } 127 128 int 129 safe_getrusage(const char *file, const int lineno, void (*cleanup_fn) (void), 130 int who, struct rusage *usage) 131 { 132 int rval; 133 134 rval = getrusage(who, usage); 135 if (rval == -1) { 136 tst_brkm(TBROK | TERRNO, cleanup_fn, 137 "%s:%d: getrusage(%d,%p) failed", 138 file, lineno, who, usage); 139 } 140 141 return rval; 142 } 143 144 void *safe_malloc(const char *file, const int lineno, void (*cleanup_fn) (void), 145 size_t size) 146 { 147 void *rval; 148 149 rval = malloc(size); 150 if (rval == NULL) { 151 tst_brkm(TBROK | TERRNO, cleanup_fn, 152 "%s:%d: malloc(%zu) failed", 153 file, lineno, size); 154 } 155 156 return rval; 157 } 158 159 int safe_mkdir(const char *file, const int lineno, void (*cleanup_fn) (void), 160 const char *pathname, mode_t mode) 161 { 162 int rval; 163 164 rval = mkdir(pathname, mode); 165 if (rval == -1) { 166 tst_brkm(TBROK | TERRNO, cleanup_fn, 167 "%s:%d: mkdir(%s,0%o) failed", 168 file, lineno, pathname, mode); 169 } 170 171 return (rval); 172 } 173 174 int safe_rmdir(const char *file, const int lineno, void (*cleanup_fn) (void), 175 const char *pathname) 176 { 177 int rval; 178 179 rval = rmdir(pathname); 180 if (rval == -1) { 181 tst_brkm(TBROK | TERRNO, cleanup_fn, 182 "%s:%d: rmdir(%s) failed", 183 file, lineno, pathname); 184 } 185 186 return (rval); 187 } 188 189 int safe_munmap(const char *file, const int lineno, void (*cleanup_fn) (void), 190 void *addr, size_t length) 191 { 192 int rval; 193 194 rval = munmap(addr, length); 195 if (rval == -1) { 196 tst_brkm(TBROK | TERRNO, cleanup_fn, 197 "%s:%d: munmap(%p,%zu) failed", 198 file, lineno, addr, length); 199 } 200 201 return rval; 202 } 203 204 int safe_open(const char *file, const int lineno, void (*cleanup_fn) (void), 205 const char *pathname, int oflags, ...) 206 { 207 va_list ap; 208 int rval; 209 mode_t mode; 210 211 va_start(ap, oflags); 212 mode = va_arg(ap, mode_t); 213 va_end(ap); 214 215 rval = open(pathname, oflags, mode); 216 if (rval == -1) { 217 tst_brkm(TBROK | TERRNO, cleanup_fn, 218 "%s:%d: open(%s,%d,0%o) failed", 219 file, lineno, pathname, oflags, mode); 220 } 221 222 return rval; 223 } 224 225 int safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void), 226 int fildes[2]) 227 { 228 int rval; 229 230 rval = pipe(fildes); 231 if (rval == -1) { 232 tst_brkm(TBROK | TERRNO, cleanup_fn, 233 "%s:%d: pipe({%d,%d}) failed", 234 file, lineno, fildes[0], fildes[1]); 235 } 236 237 return rval; 238 } 239 240 ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void), 241 char len_strict, int fildes, void *buf, size_t nbyte) 242 { 243 ssize_t rval; 244 245 rval = read(fildes, buf, nbyte); 246 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) { 247 tst_brkm(TBROK | TERRNO, cleanup_fn, 248 "%s:%d: read(%d,%p,%zu) failed, returned %zd", 249 file, lineno, fildes, buf, nbyte, rval); 250 } 251 252 return rval; 253 } 254 255 ssize_t safe_pread(const char *file, const int lineno, void (*cleanup_fn)(void), 256 char len_strict, int fildes, void *buf, size_t nbyte, 257 off_t offset) 258 { 259 ssize_t rval; 260 261 rval = pread(fildes, buf, nbyte, offset); 262 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) { 263 tst_brkm(TBROK | TERRNO, cleanup_fn, 264 "%s:%d: read(%d,%p,%zu,%ld) failed, returned %zd", 265 file, lineno, fildes, buf, nbyte, offset, rval); 266 } 267 268 return rval; 269 } 270 271 int safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void), 272 gid_t egid) 273 { 274 int rval; 275 276 rval = setegid(egid); 277 if (rval == -1) { 278 tst_brkm(TBROK | TERRNO, cleanup_fn, 279 "%s:%d: setegid(%u) failed", 280 file, lineno, (unsigned) egid); 281 } 282 283 return rval; 284 } 285 286 int safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void), 287 uid_t euid) 288 { 289 int rval; 290 291 rval = seteuid(euid); 292 if (rval == -1) { 293 tst_brkm(TBROK | TERRNO, cleanup_fn, 294 "%s:%d: seteuid(%u) failed", 295 file, lineno, (unsigned) euid); 296 } 297 298 return rval; 299 } 300 301 int safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void), 302 gid_t gid) 303 { 304 int rval; 305 306 rval = setgid(gid); 307 if (rval == -1) { 308 tst_brkm(TBROK | TERRNO, cleanup_fn, 309 "%s:%d: setgid(%u) failed", 310 file, lineno, (unsigned) gid); 311 } 312 313 return rval; 314 } 315 316 int safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void), 317 uid_t uid) 318 { 319 int rval; 320 321 rval = setuid(uid); 322 if (rval == -1) { 323 tst_brkm(TBROK | TERRNO, cleanup_fn, 324 "%s:%d: setuid(%u) failed", 325 file, lineno, (unsigned) uid); 326 } 327 328 return rval; 329 } 330 331 int 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 346 int 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 361 int safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void), 362 const char *pathname) 363 { 364 int rval; 365 366 rval = unlink(pathname); 367 if (rval == -1) { 368 tst_brkm(TBROK | TERRNO, cleanup_fn, 369 "%s:%d: unlink(%s) failed", 370 file, lineno, pathname); 371 } 372 373 return rval; 374 } 375 376 377 int 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, 387 "%s:%d: link(%s,%s) failed", 388 file, lineno, oldpath, newpath); 389 } 390 391 return rval; 392 } 393 394 int safe_linkat(const char *file, const int lineno, 395 void (cleanup_fn)(void), int olddirfd, const char *oldpath, 396 int newdirfd, const char *newpath, int flags) 397 { 398 int rval; 399 400 rval = linkat(olddirfd, oldpath, newdirfd, newpath, flags); 401 402 if (rval == -1) { 403 tst_brkm(TBROK | TERRNO, cleanup_fn, 404 "%s:%d: linkat(%d,%s,%d,%s,%d) failed", 405 file, lineno, olddirfd, oldpath, newdirfd, 406 newpath, flags); 407 } 408 409 return rval; 410 } 411 412 ssize_t safe_readlink(const char *file, const int lineno, 413 void (cleanup_fn)(void), const char *path, 414 char *buf, size_t bufsize) 415 { 416 ssize_t rval; 417 418 rval = readlink(path, buf, bufsize); 419 420 if (rval == -1) { 421 tst_brkm(TBROK | TERRNO, cleanup_fn, 422 "%s:%d: readlink(%s,%p,%zu) failed", 423 file, lineno, path, buf, bufsize); 424 } 425 426 return rval; 427 } 428 429 int safe_symlink(const char *file, const int lineno, 430 void (cleanup_fn)(void), const char *oldpath, 431 const char *newpath) 432 { 433 int rval; 434 435 rval = symlink(oldpath, newpath); 436 437 if (rval == -1) { 438 tst_brkm(TBROK | TERRNO, cleanup_fn, 439 "%s:%d: symlink(%s,%s) failed", 440 file, lineno, oldpath, newpath); 441 } 442 443 return rval; 444 } 445 446 ssize_t safe_write(const char *file, const int lineno, void (cleanup_fn) (void), 447 char len_strict, int fildes, const void *buf, size_t nbyte) 448 { 449 ssize_t rval; 450 451 rval = write(fildes, buf, nbyte); 452 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) { 453 tst_brkm(TBROK | TERRNO, cleanup_fn, 454 "%s:%d: write(%d,%p,%zu) failed", 455 file, lineno, fildes, buf, rval); 456 } 457 458 return rval; 459 } 460 461 ssize_t safe_pwrite(const char *file, const int lineno, 462 void (cleanup_fn) (void), char len_strict, int fildes, 463 const void *buf, size_t nbyte, off_t offset) 464 { 465 ssize_t rval; 466 467 rval = pwrite(fildes, buf, nbyte, offset); 468 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) { 469 tst_brkm(TBROK | TERRNO, cleanup_fn, 470 "%s:%d: pwrite(%d,%p,%zu,%ld) failed", 471 file, lineno, fildes, buf, rval, offset); 472 } 473 474 return rval; 475 } 476 477 long safe_strtol(const char *file, const int lineno, 478 void (cleanup_fn) (void), char *str, long min, long max) 479 { 480 long rval; 481 char *endptr; 482 483 errno = 0; 484 rval = strtol(str, &endptr, 10); 485 486 if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN)) 487 || (errno != 0 && rval == 0)) { 488 tst_brkm(TBROK | TERRNO, cleanup_fn, 489 "%s:%d: strtol(%s) failed", file, lineno, str); 490 } 491 492 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) { 493 tst_brkm(TBROK, cleanup_fn, 494 "%s:%d: strtol(%s): Invalid value", file, lineno, str); 495 } 496 497 if (rval > max || rval < min) { 498 tst_brkm(TBROK, cleanup_fn, 499 "%s:%d: strtol(%s): %ld is out of range %ld - %ld", 500 file, lineno, str, rval, min, max); 501 } 502 503 return rval; 504 } 505 506 unsigned long safe_strtoul(const char *file, const int lineno, 507 void (cleanup_fn) (void), char *str, 508 unsigned long min, unsigned long max) 509 { 510 unsigned long rval; 511 char *endptr; 512 513 errno = 0; 514 rval = strtoul(str, &endptr, 10); 515 516 if ((errno == ERANGE && rval == ULONG_MAX) 517 || (errno != 0 && rval == 0)) { 518 tst_brkm(TBROK | TERRNO, cleanup_fn, 519 "%s:%d: strtoul(%s) failed", file, lineno, str); 520 } 521 522 if (rval > max || rval < min) { 523 tst_brkm(TBROK, cleanup_fn, 524 "%s:%d: strtoul(%s): %lu is out of range %lu - %lu", 525 file, lineno, str, rval, min, max); 526 } 527 528 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) { 529 tst_brkm(TBROK, cleanup_fn, 530 "Invalid value: '%s' at %s:%d", str, file, lineno); 531 } 532 533 return rval; 534 } 535 536 long safe_sysconf(const char *file, const int lineno, 537 void (cleanup_fn) (void), int name) 538 { 539 long rval; 540 errno = 0; 541 542 rval = sysconf(name); 543 544 if (rval == -1) { 545 if (errno) { 546 tst_brkm(TBROK | TERRNO, cleanup_fn, 547 "%s:%d: sysconf(%d) failed", 548 file, lineno, name); 549 } else { 550 tst_resm(TINFO, "%s:%d: sysconf(%d): " 551 "queried option is not available" 552 " or there is no definite limit", 553 file, lineno, name); 554 } 555 } 556 557 return rval; 558 } 559 560 int safe_chmod(const char *file, const int lineno, 561 void (cleanup_fn)(void), const char *path, mode_t mode) 562 { 563 int rval; 564 565 rval = chmod(path, mode); 566 567 if (rval == -1) { 568 tst_brkm(TBROK | TERRNO, cleanup_fn, 569 "%s:%d: chmod(%s,0%o) failed", 570 file, lineno, path, mode); 571 } 572 573 return rval; 574 } 575 576 int safe_fchmod(const char *file, const int lineno, 577 void (cleanup_fn)(void), int fd, mode_t mode) 578 { 579 int rval; 580 581 rval = fchmod(fd, mode); 582 583 if (rval == -1) { 584 tst_brkm(TBROK | TERRNO, cleanup_fn, 585 "%s:%d: fchmod(%d,0%o) failed", 586 file, lineno, fd, mode); 587 } 588 589 return rval; 590 } 591 592 int safe_chown(const char *file, const int lineno, void (cleanup_fn)(void), 593 const char *path, uid_t owner, gid_t group) 594 { 595 int rval; 596 597 rval = chown(path, owner, group); 598 599 if (rval == -1) { 600 tst_brkm(TBROK | TERRNO, cleanup_fn, 601 "%s:%d: chown(%s,%d,%d) failed", 602 file, lineno, path, owner, group); 603 } 604 605 return rval; 606 } 607 608 int safe_fchown(const char *file, const int lineno, void (cleanup_fn)(void), 609 int fd, uid_t owner, gid_t group) 610 { 611 int rval; 612 613 rval = fchown(fd, owner, group); 614 615 if (rval == -1) { 616 tst_brkm(TBROK | TERRNO, cleanup_fn, 617 "%s:%d: fchown(%d,%d,%d) failed", 618 file, lineno, fd, owner, group); 619 } 620 621 return rval; 622 } 623 624 pid_t safe_wait(const char *file, const int lineno, void (cleanup_fn)(void), 625 int *status) 626 { 627 pid_t rval; 628 629 rval = wait(status); 630 if (rval == -1) { 631 tst_brkm(TBROK | TERRNO, cleanup_fn, 632 "%s:%d: wait(%p) failed", 633 file, lineno, status); 634 } 635 636 return rval; 637 } 638 639 pid_t safe_waitpid(const char *file, const int lineno, void (cleanup_fn)(void), 640 pid_t pid, int *status, int opts) 641 { 642 pid_t rval; 643 644 rval = waitpid(pid, status, opts); 645 if (rval == -1) { 646 tst_brkm(TBROK | TERRNO, cleanup_fn, 647 "%s:%d: waitpid(%d,%p,%d) failed", 648 file, lineno, pid, status, opts); 649 } 650 651 return rval; 652 } 653 654 void *safe_memalign(const char *file, const int lineno, 655 void (*cleanup_fn) (void), size_t alignment, size_t size) 656 { 657 void *rval; 658 659 rval = memalign(alignment, size); 660 if (rval == NULL) 661 tst_brkm(TBROK | TERRNO, cleanup_fn, "memalign failed at %s:%d", 662 file, lineno); 663 664 return rval; 665 } 666 667 int safe_kill(const char *file, const int lineno, void (cleanup_fn)(void), 668 pid_t pid, int sig) 669 { 670 int rval; 671 672 rval = kill(pid, sig); 673 674 if (rval == -1) { 675 tst_brkm(TBROK | TERRNO, cleanup_fn, 676 "%s:%d: kill(%d,%s) failed", 677 file, lineno, pid, tst_strsig(sig)); 678 } 679 680 return rval; 681 } 682 683 int safe_mkfifo(const char *file, const int lineno, 684 void (*cleanup_fn)(void), const char *pathname, mode_t mode) 685 { 686 int rval; 687 688 rval = mkfifo(pathname, mode); 689 690 if (rval == -1) { 691 tst_brkm(TBROK | TERRNO, cleanup_fn, 692 "%s:%d: mkfifo(%s, 0%o) failed", 693 file, lineno, pathname, mode); 694 } 695 696 return rval; 697 } 698 699 int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void), 700 const char *oldpath, const char *newpath) 701 { 702 int rval; 703 704 rval = rename(oldpath, newpath); 705 706 if (rval == -1) { 707 tst_brkm(TBROK | TERRNO, cleanup_fn, 708 "%s:%d: rename(%s, %s) failed", 709 file, lineno, oldpath, newpath); 710 } 711 712 return rval; 713 } 714 715 int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void), 716 const char *source, const char *target, 717 const char *filesystemtype, unsigned long mountflags, 718 const void *data) 719 { 720 int rval; 721 722 rval = mount(source, target, filesystemtype, mountflags, data); 723 724 if (rval == -1) { 725 tst_brkm(TBROK | TERRNO, cleanup_fn, 726 "%s:%d: mount(%s, %s, %s, %lu, %p) failed", 727 file, lineno, source, target, filesystemtype, 728 mountflags, data); 729 } 730 731 return rval; 732 } 733 734 int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void), 735 const char *target) 736 { 737 int rval; 738 739 rval = umount(target); 740 741 if (rval == -1) { 742 tst_brkm(TBROK | TERRNO, cleanup_fn, 743 "%s:%d: umount(%s) failed", 744 file, lineno, target); 745 } 746 747 return rval; 748 } 749 750 DIR* safe_opendir(const char *file, const int lineno, void (cleanup_fn)(void), 751 const char *name) 752 { 753 DIR *rval; 754 755 rval = opendir(name); 756 757 if (!rval) { 758 tst_brkm(TBROK | TERRNO, cleanup_fn, 759 "%s:%d: opendir(%s) failed", file, lineno, name); 760 } 761 762 return rval; 763 } 764 765 int safe_closedir(const char *file, const int lineno, void (cleanup_fn)(void), 766 DIR *dirp) 767 { 768 int rval; 769 770 rval = closedir(dirp); 771 772 if (rval) { 773 tst_brkm(TBROK | TERRNO, cleanup_fn, 774 "%s:%d: closedir(%p) failed", file, lineno, dirp); 775 } 776 777 return rval; 778 } 779 780 struct dirent *safe_readdir(const char *file, const int lineno, void (cleanup_fn)(void), 781 DIR *dirp) 782 { 783 struct dirent *rval; 784 int err = errno; 785 786 errno = 0; 787 rval = readdir(dirp); 788 789 if (!rval && errno) { 790 tst_brkm(TBROK | TERRNO, cleanup_fn, 791 "%s:%d: readdir(%p) failed", file, lineno, dirp); 792 } 793 794 errno = err; 795 return rval; 796 } 797