1# This file is sourced by init.sh, *before* its initialization. 2 3# Copyright (C) 2010-2023 Free Software Foundation, Inc. 4 5# This program is free software: you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18# This goes hand in hand with the "exec 9>&2;" in tests/Makefile.am's 19# TESTS_ENVIRONMENT definition. 20stderr_fileno_=9 21 22# Having an unsearchable directory in PATH causes execve to fail with EACCES 23# when applied to an unresolvable program name, contrary to the desired ENOENT. 24# Avoid the problem by rewriting PATH to exclude unsearchable directories. 25# Also, if PATH lacks /sbin and/or /usr/sbin, append it/them. 26sanitize_path_() 27{ 28 # FIXME: remove double quotes around $IFS when all tests use init.sh. 29 # They constitute a work-around for a bug in FreeBSD 8.1's /bin/sh. 30 local saved_IFS="$IFS" 31 IFS=: 32 set -- $PATH 33 IFS=$saved_IFS 34 35 local d d1 36 local colon= 37 local new_path= 38 for d in "$@"; do 39 test -z "$d" && d1=. || d1=$d 40 if ls -d "$d1/." > /dev/null 2>&1; then 41 new_path="$new_path$colon$d" 42 colon=':' 43 fi 44 done 45 46 for d in /sbin /usr/sbin ; do 47 case ":$new_path:" in 48 *:$d:*) ;; 49 *) new_path="$new_path:$d" ;; 50 esac 51 done 52 53 PATH=$new_path 54 export PATH 55} 56 57getlimits_() 58{ 59 eval $(getlimits) 60 test "$INT_MAX" || fatal_ "running getlimits" 61} 62 63require_no_default_acl_() 64{ 65 if getfacl --version < /dev/null > /dev/null 2>&1; then 66 getfacl "$1" | grep '^default:' && skip_ 'Default ACL detected' 67 else 68 ls -ld "$1" | grep '.........+' && skip_ 'ACL detected' 69 fi 70} 71 72require_acl_() 73{ 74 getfacl --version < /dev/null > /dev/null 2>&1 \ 75 && setfacl --version < /dev/null > /dev/null 2>&1 \ 76 || skip_ "This test requires getfacl and setfacl." 77 78 id -u bin > /dev/null 2>&1 \ 79 || skip_ "This test requires a local user named bin." 80} 81 82is_local_dir_() 83{ 84 test $# = 1 || framework_failure_ 85 df --local "$1" >/dev/null 2>&1 86} 87 88require_mount_list_() 89{ 90 local mount_list_fail='cannot read table of mounted file systems' 91 df --local 2>&1 | grep -F "$mount_list_fail" >/dev/null && 92 skip_ "$mount_list_fail" 93} 94 95dump_mount_list_() 96{ 97 cat /proc/self/mountinfo || 98 cat /proc/self/mounts || 99 cat /proc/mounts || 100 cat /etc/mtab 101} 102 103require_local_dir_() 104{ 105 require_mount_list_ 106 is_local_dir_ . || 107 skip_ "This test must be run on a local file system." 108} 109 110require_selinux_() 111{ 112 # When in a chroot of an SELinux-enabled system, but with a mock-simulated 113 # SELinux-*disabled* system, recognize that SELinux is disabled system wide: 114 grep 'selinuxfs$' /proc/filesystems > /dev/null \ 115 || skip_ "this system lacks SELinux support" 116 117 # Independent of whether SELinux is enabled system-wide, 118 # the current file system may lack SELinux support. 119 # Also the current build may have SELinux support disabled. 120 case $(ls -Zd .) in 121 '? .'|'unlabeled .') 122 test -z "$CONFIG_HEADER" \ 123 && framework_failure_ 'CONFIG_HEADER not defined' 124 grep '^#define HAVE_SELINUX_SELINUX_H 1' "$CONFIG_HEADER" > /dev/null \ 125 && selinux_missing_="(file) system" || selinux_missing_="build" 126 skip_ "this $selinux_missing_ lacks SELinux support" 127 ;; 128 esac 129} 130 131# Return the SELinux type component if available 132get_selinux_type() { ls -Zd "$1" | sed -n 's/.*:\(.*_t\)[: ].*/\1/p'; } 133 134# Whether SELinux Multi Level Security is enabled 135mls_enabled_() { 136 sestatus 2>&1 | 137 grep 'Policy MLS status:.*enabled' > /dev/null 138} 139 140# Skip this test if we're not in SELinux "enforcing" mode. 141require_selinux_enforcing_() 142{ 143 require_selinux_ 144 test "$(getenforce)" = Enforcing \ 145 || skip_ "This test is useful only with SELinux in Enforcing mode." 146} 147 148require_smack_() 149{ 150 grep 'smackfs$' /proc/filesystems > /dev/null \ 151 || skip_ "this system lacks SMACK support" 152 153 test "$(ls -Zd .)" != '? .' \ 154 || skip_ "this file system lacks SMACK support" 155} 156 157require_openat_support_() 158{ 159 # Skip this test if your system has neither the openat-style functions 160 # nor /proc/self/fd support with which to emulate them. 161 162 test -z "$CONFIG_HEADER" \ 163 && framework_failure_ 'CONFIG_HEADER not defined' 164 165 _skip=yes 166 grep '^#define HAVE_OPENAT' "$CONFIG_HEADER" > /dev/null && _skip=no 167 test -d /proc/self/fd && _skip=no 168 if test $_skip = yes; then 169 skip_ 'this system lacks openat support' 170 fi 171} 172 173# Return true if command runs with the 174# ulimit specified in the first argument 175ulimit_supported_() 176{ 177 local v 178 v="$1" 179 shift 180 181 ( 182 # Try to disable core dumps which may 183 # occur with memory constraints 184 trap '' SEGV; ulimit -c 0; 185 186 ulimit -v $v && "$@" 187 ) >/dev/null 2>&1 188} 189 190# Determine the minimum required VM limit to run the given command. 191# Output that value to stdout ... to be used by the caller. 192# Return 0 in case of success, and a non-Zero value otherwise. 193get_min_ulimit_v_() 194{ 195 local v 196 local page_size 197 198 # Increase result by this amount to avoid alignment issues 199 page_size=$(getconf PAGESIZE || echo 4096) 200 page_size=$(($page_size / 1024)) 201 202 for v in $( seq 5000 5000 50000 ); do 203 if ulimit_supported_ $v "$@"; then 204 local prev_v 205 prev_v=$v 206 for v in $( seq $(($prev_v-1000)) -1000 1000 ); do 207 ulimit_supported_ $v "$@" || 208 { 209 ret_v=$((prev_v + $page_size)) 210 echo $ret_v 211 return 0 212 } 213 prev_v=$v 214 done 215 fi 216 done 217 # The above did not find a working limit. Echo a very small number - just 218 # in case the caller does not handle the non-Zero return value. 219 echo 1; return 1 220} 221 222require_readable_root_() 223{ 224 test -r / || skip_ "/ is not readable" 225} 226 227# Skip the current test if strace is not available or doesn't work 228# with the named syscall. Usage: require_strace_ unlink 229require_strace_() 230{ 231 test $# = 1 || framework_failure_ 232 233 strace -V < /dev/null > /dev/null 2>&1 || 234 skip_ 'no strace program' 235 236 strace -qe "$1" echo > /dev/null 2>&1 || 237 skip_ 'strace -qe "'"$1"'" does not work' 238 239 # On some linux/sparc64 systems, strace works fine on 32-bit executables, 240 # but prints only one line of output for every 64-bit executable. 241 strace -o log-help ls --help >/dev/null || framework_failure_ 242 n_lines_help=$(wc -l < log-help) 243 rm -f log-help 244 if test $n_lines_help = 0 || test $n_lines_help = 1; then 245 skip_ 'strace produces no more than one line of output' 246 fi 247} 248 249# Skip the current test if valgrind doesn't work, 250# which could happen if not installed, 251# or hasn't support for the built architecture, 252# or hasn't appropriate error suppressions installed etc. 253require_valgrind_() 254{ 255 valgrind --error-exitcode=1 true 2>/dev/null || 256 skip_ "requires a working valgrind" 257} 258 259# Skip the current test if setfacl doesn't work on the current file system, 260# which could happen if not installed, or if ACLs are not supported by the 261# kernel or the file system, or are turned off via mount options. 262# 263# Work around the following two issues: 264# 265# 1) setfacl maps ACLs into file permission bits if on "noacl" file systems. 266# 267# On file systems which do not support ACLs (e.g. ext4 mounted with -o noacl), 268# setfacl operates on the regular file permission bits, and only fails if the 269# given ACL spec does not fit into there. Thus, to test if ACLs really work 270# on the current file system, pass an ACL spec which can't be mapped that way. 271# "Default" ACLs (-d) seem to fulfill this requirement. 272# 273# 2) setfacl only invokes the underlying system call if the ACL would change. 274# 275# If the given ACL spec would not change the ACLs on the file, then setfacl 276# does not invoke the underlying system call - setxattr(). Therefore, to test 277# if setting ACLs really works on the current file system, call setfacl twice 278# with conflicting ACL specs. 279require_setfacl_() 280{ 281 local d='acltestdir_' 282 mkdir $d || framework_failure_ 283 local f=0 284 285 setfacl -d -m user::r-x $d \ 286 && setfacl -d -m user::rwx $d \ 287 || f=1 288 rm -rf $d || framework_failure_ 289 test $f = 0 \ 290 || skip_ "setfacl does not work on the current file system" 291} 292 293# Require a controlling input 'terminal'. 294require_controlling_input_terminal_() 295{ 296 have_input_tty=yes 297 tty -s || have_input_tty=no 298 test -t 0 || have_input_tty=no 299 if test "$have_input_tty" = no; then 300 skip_ 'requires controlling input terminal 301This test must have a controlling input "terminal", so it may not be 302run via "batch", "at", or "ssh". On some systems, it may not even be 303run in the background.' 304 fi 305} 306 307require_built_() 308{ 309 skip_=no 310 for i in "$@"; do 311 case " $built_programs " in 312 *" $i "*) ;; 313 *) echo "$i: not built" 1>&2; skip_=yes ;; 314 esac 315 done 316 317 test $skip_ = yes && skip_ "required program(s) not built" 318} 319 320require_file_system_bytes_free_() 321{ 322 local req=$1 323 local expr=$(stat -f --printf "$req / %S <= %a" .) 324 $AWK "BEGIN{ exit !($expr) }" \ 325 || skip_ "this test needs at least $req bytes of free space" 326} 327 328uid_is_privileged_() 329{ 330 # Make sure id -u succeeds. 331 my_uid=$(id -u) \ 332 || { echo "$0: cannot run 'id -u'" 1>&2; return 1; } 333 334 # Make sure it gives valid output. 335 case $my_uid in 336 0) ;; 337 *[!0-9]*) 338 echo "$0: invalid output ('$my_uid') from 'id -u'" 1>&2 339 return 1 ;; 340 *) return 1 ;; 341 esac 342} 343 344get_process_status_() 345{ 346 sed -n '/^State:[ ]*\([[:alpha:]]\).*/s//\1/p' /proc/$1/status 347} 348 349# Convert an ls-style permission string, like drwxr----x and -rw-r-x-wx 350# to the equivalent chmod --mode (-m) argument, (=,u=rwx,g=r,o=x and 351# =,u=rw,g=rx,o=wx). Ignore ACLs. 352rwx_to_mode_() 353{ 354 case $# in 355 1) rwx=$1;; 356 *) echo "$0: wrong number of arguments" 1>&2 357 echo "Usage: $0 ls-style-mode-string" 1>&2 358 return;; 359 esac 360 361 case $rwx in 362 [ld-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxtT-]) ;; 363 [ld-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxsS-][rwx-][rwx-][rwxtT-][+.]) ;; 364 *) echo "$0: invalid mode string: $rwx" 1>&2; return;; 365 esac 366 367 # Perform these conversions: 368 # S s 369 # s xs 370 # T t 371 # t xt 372 # The 'T' and 't' ones are only valid for 'other'. 373 s='s/S/@/;s/s/x@/;s/@/s/' 374 t='s/T/@/;s/t/x@/;s/@/t/' 375 376 u=$(echo $rwx|sed 's/^.\(...\).*/,u=\1/;s/-//g;s/^,u=$//;'$s) 377 g=$(echo $rwx|sed 's/^....\(...\).*/,g=\1/;s/-//g;s/^,g=$//;'$s) 378 o=$(echo $rwx|sed 's/^.......\(...\).*/,o=\1/;s/-//g;s/^,o=$//;'$s';'$t) 379 echo "=$u$g$o" 380} 381 382# Set the global variable stty_reversible_ to a space-separated list of the 383# reversible settings from stty.c. stty_reversible_ also starts and ends 384# with a space. 385stty_reversible_init_() 386{ 387 require_perl_ 388 # Pad start with one space for the first option to match in query function. 389 stty_reversible_=' '$(perl -lne '/^ *{"(.*?)",.*\bREV\b/ and print $1' \ 390 "$abs_top_srcdir"/src/stty.c | tr '\n' ' ') 391 # Ensure that there are at least 62, i.e., so we're alerted if 392 # reformatting the source empties the list. 393 test 62 -le $(echo "$stty_reversible_"|wc -w) \ 394 || framework_failure_ "too few reversible settings" 395} 396 397# Test whether $1 is one of stty's reversible options. 398stty_reversible_query_() 399{ 400 case $stty_reversible_ in 401 '') 402 framework_failure_ "stty_reversible_init_() not called?";; 403 *" $1 "*) 404 return 0;; 405 *) 406 return 1;; 407 esac 408} 409 410skip_if_() 411{ 412 case $1 in 413 root) skip_ must be run as root ;; 414 non-root) skip_ must be run as non-root ;; 415 *) ;; # FIXME? 416 esac 417} 418 419very_expensive_() 420{ 421 if test "$RUN_VERY_EXPENSIVE_TESTS" != yes; then 422 skip_ 'very expensive: disabled by default 423This test is very expensive, so it is disabled by default. 424To run it anyway, rerun make check with the RUN_VERY_EXPENSIVE_TESTS 425environment variable set to yes. E.g., 426 427 env RUN_VERY_EXPENSIVE_TESTS=yes make check 428 429or use the shortcut target of the toplevel Makefile, 430 431 make check-very-expensive 432' 433 fi 434} 435 436expensive_() 437{ 438 if test "$RUN_EXPENSIVE_TESTS" != yes; then 439 skip_ 'expensive: disabled by default 440This test is relatively expensive, so it is disabled by default. 441To run it anyway, rerun make check with the RUN_EXPENSIVE_TESTS 442environment variable set to yes. E.g., 443 444 env RUN_EXPENSIVE_TESTS=yes make check 445 446or use the shortcut target of the toplevel Makefile, 447 448 make check-expensive 449' 450 fi 451} 452 453# Test whether we can run our just-built root owned rm, 454# i.e., that $NON_ROOT_USERNAME has access to the build directory. 455nonroot_has_perm_() 456{ 457 require_built_ chroot 458 459 local rm_version=$( 460 chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ 461 rm --version | 462 sed -n '1s/.* //p' 463 ) 464 case ":$rm_version:" in 465 :$PACKAGE_VERSION:) ;; 466 *) return 1;; 467 esac 468} 469 470require_root_() 471{ 472 uid_is_privileged_ || skip_ "must be run as root" 473 NON_ROOT_USERNAME=${NON_ROOT_USERNAME=nobody} 474 NON_ROOT_GID=${NON_ROOT_GID=$(id -g $NON_ROOT_USERNAME)} 475 476 # When the current test invokes chroot, call nonroot_has_perm_ 477 # to check for a common problem. 478 grep '^[ ]*chroot' "../$0" \ 479 && { nonroot_has_perm_ \ 480 || skip_ "user $NON_ROOT_USERNAME lacks execute permissions"; } 481} 482 483skip_if_root_() { uid_is_privileged_ && skip_ "must be run as non-root"; } 484 485# Set 'groups' to a space-separated list of at least two groups 486# of which the user is a member. 487require_membership_in_two_groups_() 488{ 489 test $# = 0 || framework_failure_ 490 491 groups= 492 for group_ in 1 \ 493 ${COREUTILS_GROUPS-$( (id -G || /usr/xpg4/bin/id -G) 2>/dev/null)} 494 do 495 # Skip group numbers equal to 2**N - 1 for common N, 496 # as they are possibly reserved groups like 'nogroup'. 497 case $group_ in 498 1 | 32767 | 65535 | 2147483647 | 4294967295) ;; 499 9223372036854775807 | 18446744073709551615) ;; 500 *) test -z "$groups" || groups="$groups " 501 groups="$groups$group_";; 502 esac 503 done 504 case "$groups" in 505 *' '*) ;; 506 *) skip_ 'requires membership in two groups 507this test requires that you be a member of more than one group, 508but running '\''id -G'\'' either failed or found just one. If you really 509are a member of at least two groups, then rerun this test with 510COREUTILS_GROUPS set in your environment to the space-separated list 511of group names or numbers. E.g., 512 513 env COREUTILS_GROUPS='\''users cdrom'\'' make check 514 515' 516 ;; 517 esac 518} 519 520# Is /proc/$PID/status supported? 521require_proc_pid_status_() 522{ 523 sleep 2 & 524 local pid=$! 525 sleep .5 526 grep '^State:[ ]*[S]' /proc/$pid/status > /dev/null 2>&1 || 527 skip_ "/proc/$pid/status: missing or 'different'" 528 kill $pid 529} 530 531# Does trap support signal names? 532# Old versions of ash did not. 533require_trap_signame_() 534{ 535 (trap '' CHLD) || skip_ 'requires trap with signal name support' 536} 537 538# Does kill support sending signal to whole group? 539# dash 0.5.8 at least does not. 540require_kill_group_() 541{ 542 kill -0 -- -1 || skip_ 'requires kill with group signaling support' 543} 544 545# Return nonzero if the specified path is on a file system for 546# which SEEK_DATA support exists. 547seek_data_capable_() 548{ 549 # Check that SEEK_HOLE support is enabled 550 # Note APFS was seen to not create sparse files < 16MiB 551 if ! truncate -s16M file.sparse_; then 552 warn_ "can't create a sparse file: assuming not SEEK_DATA capable" 553 return 1 554 fi 555 if ! cp --debug --reflink=never file.sparse_ file.sparse_.cp \ 556 | grep SEEK_HOLE; then 557 return 1 558 fi 559 560 # Check that SEEK_HOLE is supported on the passed file 561 { python3 < /dev/null && PYTHON_=python3; } || 562 { python < /dev/null && PYTHON_=python; } 563 564 if test x"$PYTHON_" = x; then 565 warn_ 'seek_data_capable_: python missing: assuming not SEEK_DATA capable' 566 return 1 567 fi 568 569 # Use timeout if available to skip cases where SEEK_DATA takes a long time. 570 # We saw FreeBSD 9.1 take 35s to return from SEEK_DATA for a 1TiB empty file. 571 # Note lseek() is uninterruptible on FreeBSD 9.1, but it does eventually 572 # return, and the timeout will ensure a failure return from the process. 573 timeout --version >/dev/null && TIMEOUT_='timeout 10' 574 575 $TIMEOUT_ $PYTHON_ "$abs_srcdir"/tests/seek-data-capable "$@" 576} 577 578# Skip the current test if "." lacks d_type support. 579require_dirent_d_type_() 580{ 581 python < /dev/null \ 582 || skip_ python missing: assuming no d_type support 583 584 python "$abs_srcdir"/tests/d_type-check \ 585 || skip_ requires d_type support 586} 587 588# Skip the current test if we lack Perl. 589require_perl_() 590{ 591 : ${PERL=perl} 592 $PERL -e 'use warnings' > /dev/null 2>&1 \ 593 || skip_ 'configure did not find a usable version of Perl' 594} 595 596# Does the current (working-dir) file system support sparse files? 597require_sparse_support_() 598{ 599 test $# = 0 || framework_failure_ 600 # Test whether we can create a sparse file. 601 # For example, on Darwin6.5 with a file system of type hfs, it's not possible. 602 # NTFS requires 128K before a hole appears in a sparse file. 603 t=sparse.$$ 604 dd bs=1 seek=128K of=$t < /dev/null 2> /dev/null 605 set x $(du -sk $t) 606 kb_size=$2 607 rm -f $t 608 if test $kb_size -ge 128; then 609 skip_ 'this file system does not support sparse files' 610 fi 611} 612 613# Libraries needed when we compile a shared library. 614gcc_shared_libs_= 615 616# Compile a shared lib using the GCC options for doing so. 617# Pass input and output file as parameters respectively. 618# Any other optional parameters are passed to $CC. 619gcc_shared_() 620{ 621 local in=$1 622 local out=$2 623 shift 2 || return 1 624 625 $CC -Wall -shared --std=gnu99 -fPIC -O2 $* "$in" -o "$out" $gcc_shared_libs_ 626} 627 628# There are a myriad of ways to build shared libs, 629# so we only consider running tests requiring shared libs, 630# on platforms that support building them as follows. 631require_gcc_shared_() 632{ 633 # Try two different values for gcc_shared_libs_. 634 gcc_shared_libs_='-ldl' 635 if gcc_shared_ '-' 'd.so' -xc < /dev/null 2>&1; then 636 : 637 else 638 gcc_shared_libs_= 639 if gcc_shared_ '-' 'd.so' -xc < /dev/null 2>&1; then 640 : 641 else 642 skip_ '$CC -shared ... failed to build a shared lib' 643 fi 644 fi 645 rm -f d.so 646} 647 648mkfifo_or_skip_() 649{ 650 test $# = 1 || framework_failure_ 651 if ! mkfifo "$1"; then 652 # Make an exception of this case -- usually we interpret framework-creation 653 # failure as a test failure. However, in this case, when running on a SunOS 654 # system using a file system NFS mounted from OpenBSD, the above fails like 655 # this: 656 # mkfifo: cannot make fifo 'fifo-10558': Not owner 657 skip_ 'unable to create a fifo' 658 fi 659} 660 661trap_sigpipe_or_skip_() 662{ 663 timeout --version >/dev/null || 664 skip_ 'trapping SIGPIPE cannot be safely checked' 665 666 (trap '' PIPE && timeout 10 yes |:) 2>&1 | grep 'Broken pipe' >/dev/null || 667 skip_ 'trapping SIGPIPE is not supported' 668} 669 670require_bash_as_SHELL_() 671{ 672 if bash --version >/dev/null 2>&1; then 673 SHELL='bash' 674 else 675 skip_ 'bash is required' 676 fi 677} 678 679# Disable the current test if the working directory seems to have 680# the setgid bit set. 681skip_if_setgid_() 682{ 683 setgid_tmpdir=setgid-$$ 684 (umask 77; mkdir $setgid_tmpdir) 685 perms=$(stat --printf %A $setgid_tmpdir) 686 rmdir $setgid_tmpdir 687 case $perms in 688 drwx------);; 689 drwxr-xr-x);; # Windows98 + DJGPP 2.03 690 *) skip_ 'this directory has the setgid bit set';; 691 esac 692} 693 694# Skip if files are created with a different group to the current user 695# This can happen due to a setgid dir, or by some other mechanism on OS X: 696# https://unix.stackexchange.com/q/63865 697# https://bugs.gnu.org/14024#41 698skip_if_nondefault_group_() 699{ 700 touch grp.$$ 701 gen_ug=$(stat -c '%u:%g' grp.$$) 702 rm grp.$$ 703 test "$gen_ug" = "$(id -ru):$(id -rg)" || 704 skip_ 'Files are created with a different gid' 705} 706 707skip_if_mcstransd_is_running_() 708{ 709 test $# = 0 || framework_failure_ 710 711 # When mcstransd is running, you'll see only the 3-component 712 # version of file-system context strings. Detect that, 713 # and if it's running, skip this test. 714 __ctx=$(stat --printf='%C\n' .) || framework_failure_ 715 case $__ctx in 716 *:*:*:*) __ctx_ok=1 ;; # four components is ok 717 *:*:*) # three components is ok too if there is no MLS 718 mls_enabled_ || __ctx_ok=1 ;; 719 esac 720 721 test "$__ctx_ok" || 722 skip_ "unexpected context '$__ctx'; turn off mcstransd" 723} 724 725# Skip the current test if umask doesn't work as usual. 726# This test should be run in the temporary directory that ends 727# up being removed via the trap commands. 728working_umask_or_skip_() 729{ 730 umask 022 731 touch file1 file2 732 chmod 644 file2 733 perms=$(ls -l file1 file2 | sed 's/ .*//' | uniq) 734 rm -f file1 file2 735 736 case $perms in 737 *' 738 '*) skip_ 'your build directory has unusual umask semantics' 739 esac 740} 741 742# Retry a function requiring a sufficient delay to _pass_ 743# using a truncated exponential backoff method. 744# Example: retry_delay_ dd_reblock_1 .1 6 745# This example will call the dd_reblock_1 function with 746# an initial delay of .1 second and call it at most 6 times 747# with a max delay of 3.2s (doubled each time), or a total of 6.3s 748# Note ensure you do _not_ quote the parameter to GNU sleep in 749# your function, as it may contain separate values that sleep 750# needs to accumulate. 751# Further function arguments will be forwarded to the test function. 752retry_delay_() 753{ 754 local test_func=$1 755 local init_delay=$2 756 local max_n_tries=$3 757 shift 3 || return 1 758 759 local attempt=1 760 local num_sleeps=$attempt 761 local time_fail 762 while test $attempt -le $max_n_tries; do 763 local delay=$($AWK -v n=$num_sleeps -v s="$init_delay" \ 764 'BEGIN { print s * n }') 765 "$test_func" "$delay" "$@" && { time_fail=0; break; } || time_fail=1 766 attempt=$(expr $attempt + 1) 767 num_sleeps=$(expr $num_sleeps '*' 2) 768 done 769 test "$time_fail" = 0 770} 771 772# Call this with a list of programs under test immediately after 773# sourcing init.sh. 774print_ver_() 775{ 776 require_built_ "$@" 777 if test "$VERBOSE" = yes; then 778 local i 779 for i in $*; do 780 env $i --version 781 done 782 fi 783} 784 785# Are we running on GNU/Hurd? 786require_gnu_() 787{ 788 test "$(uname)" = GNU \ 789 || skip_ 'not running on GNU/Hurd' 790} 791 792sanitize_path_ 793