. "$BST_LIB" # BST-TIMEOUT: 300 # ~155 cases over ~100 execs of a 2.4 MB wasm module; the # 60 s default is too tight for that on a loaded host. # # rfkill 1.0 -- kernel.org's standalone radio-kill-switch tool (meta-oe # recipes-connectivity/rfkill, the tarball from www.kernel.org plus meta-oe's # two build patches). One binary; it reads and writes /dev/rfkill and reads # device names out of /sys/class/rfkill/rfkillN/name. # # THIS IS NOT util-linux's rfkill, AND TELLING THEM APART IS THE POINT OF THIS # SUITE. Both install to ${sbindir}/rfkill through update-alternatives, so the # question "which one answers?" is decided by priority, not by which package # you asked for -- and util-linux's is 80 against this recipe's 60. On this # image nothing is contested, because util-linux is present only as per-tool # split packages and util-linux-rfkill is not one of the installed ones, so the # /usr/sbin/rfkill alternative has exactly one provider. That is a fact about # the image rather than a guarantee, so the suite pins it from both ends: the # link's own target, and the VERSION AND USAGE SURFACE below, which differs so # sharply between the two programs that a swapped provider cannot pass. # util-linux's prints "rfkill from util-linux 2.39.3" and accepts # --output/--json/--noheadings; this one prints "rfkill 1.0" and accepts no # option at all except --version. # # THE TICKET ASKED FOR THREE THINGS THIS PROGRAM DOES NOT HAVE, and the suite # asserts their ABSENCE rather than quietly dropping them -- they are # util-linux's spellings, which is the same confusion the paragraph above # exists for: # --help : there is no --help. `help' is a COMMAND (rc 0); `--help' falls # through main()'s final else to usage() + return 1. # --output : not implemented. Rejected, rc 1. # --json : not implemented. Rejected, rc 1. # # THE DEVICE IS PROBED, NOT ASSUMED. The ticket expected the "CONFIG_RFKILL=y # with no switches registered" case -- /dev/rfkill opens and enumerates # nothing. This kernel is a third case it did not consider: CONFIG_RFKILL is # not set in arch/wasm32/configs/wasm32_defconfig at all, so there is no # /dev/rfkill and no /sys/class/rfkill either. That is a distro kernel-config # fact for a machine with no radios, not a defect, and it is the same class of # fact 63-tunctl records for CONFIG_TUN. Both arms are written out in full and # selected at runtime, so the day this kernel grows an rfkill subsystem the # result changes visibly instead of passing either way. # # EVERY DIAGNOSTIC rfkill PRINTS GOES TO STDERR, and only version() writes to # stdout. usage() is a run of fprintf(stderr, ...), and both "Bogus # argument" and every perror() go to stderr too -- so `rfkill list 2>/dev/null' # hides the only thing it had to say. Cases below pin that split in both # directions: a suite reading stdout alone would find nothing and read as # though rfkill had said nothing. # # ONE UPSTREAM BUG IS PINNED RATHER THAN PAPERED OVER: main() DISCARDS # rfkill_list()'s return value (`rfkill_list(*argv);', with no `ret ='), so # `list' exits 0 whatever happened -- for a bogus identifier it has already # rejected, and for a control device it could not open. `block'/`unblock' a few # lines below DO assign, and report 2 and 1 for those same two conditions, # which is what makes this an oversight rather than a policy. The ticket's # "rfkill list ... exits 0" is therefore true here, but NOT for the reason it # gives, and the paired cases below say so: the message proves the rejection # happened, the rc proves it was not propagated. LINK=/usr/sbin/rfkill ALT=/usr/sbin/rfkill.rfkill UL=/usr/sbin/rfkill.util-linux MAN=/usr/share/man/man8/rfkill.8.gz # THE GATE IS THE ALTERNATIVES TARGET, NOT `require rfkill'. `require' asks # `command -v', which cannot distinguish "this package is not on the image" (a # legitimate skip) from "the package shipped and its alternatives link was # lost" -- the exact regression the ticket names as the one that matters. With # the target present, every link case below is a real assertion and a lost link # goes RED instead of skipping the whole suite. if [ ! -f "$ALT" ]; then bst_skip rfkill/present "rfkill is not installed on this image (no $ALT)" exit 0 fi bst_ok rfkill/present tmp=${TMPDIR:-/tmp}/bst-rfkill.$$ mkdir -p "$tmp" 2>/dev/null O=$tmp/o; E=$tmp/e # cap : run it ONCE and keep stdout, stderr and status apart. Most # cases below assert on all three, and an exec is the expensive operation on # this target, so this is two forks rather than three runs of the same command. cap() { "$@" >"$O" 2>"$E"; RC=$? OUT=$(cat "$O" 2>/dev/null); ERR=$(cat "$E" 2>/dev/null) } rc_is() { # -- reads $RC/$ERR from the last cap if [ "$RC" = "$2" ]; then bst_ok "$1" elif bst_execfail "$ERR"; then bst_unrun "$1" "$ERR" else bst_notok "$1" "rc=$RC want-rc=$2 err:'$(_bst_1line "$ERR")'"; fi } inc() { # case "$3" in *"$2"*) bst_ok "$1" ;; *) if bst_execfail "$3"; then bst_unrun "$1" "$3" else bst_notok "$1" "want:'$2' got:'$(_bst_1line "$3")'"; fi ;; esac } # exc : the needle must be ABSENT -- and the haystack # must be NON-EMPTY. Without that second half every one of these passes when # the command could not be staged at all, which is a false green in exactly the # cases written to prove that a wrong binary is not answering. exc() { if [ -z "$3" ]; then bst_notok "$1" "nothing to check: the command produced no output" elif bst_execfail "$3"; then bst_unrun "$1" "$3" else case "$3" in *"$2"*) bst_notok "$1" "must not contain:'$2' got:'$(_bst_1line "$3")'" ;; *) bst_ok "$1" ;; esac; fi } is_empty() { # if [ -z "$2" ]; then bst_ok "$1" else bst_notok "$1" "expected empty, got:'$(_bst_1line "$2")'"; fi } # not_bogus : the parser ACCEPTED the identifier. The oracle is the # absence of "Bogus", which only rfkill_id_to_type()'s caller prints -- so it # holds in both device arms, where an empty stderr (device opened, nothing # enumerated) and a perror line (no device) are equally fine. `exc' cannot be # used: its non-empty guard would fire on the legitimate empty-stderr arm. not_bogus() { if bst_execfail "$ERR"; then bst_unrun "$1" "$ERR" else case "$ERR" in *Bogus*) bst_notok "$1" "the parser rejected a documented identifier: '$(_bst_1line "$ERR")'" ;; *) bst_ok "$1" ;; esac; fi } nlines() { wc -l < "$1" 2>/dev/null | tr -d ' \t'; } # ---------------------------------------------------------------- packaging --- check_eq rfkill/which "$LINK" "$(command -v rfkill)" check rfkill/link-exists test -e "$LINK" check rfkill/link-is-symlink test -L "$LINK" # update-alternatives writes the target as a BARE BASENAME, not an absolute # path -- every other alternative in this rootfs reads the same way # (printf -> printf.coreutils). check_eq rfkill/link-target "rfkill.rfkill" "$(readlink "$LINK")" check rfkill/alt-is-file test -f "$ALT" check rfkill/alt-nonempty test -s "$ALT" # `[ -x ]' IS NOT AN ORACLE ON THE VIRTIOFS ROOT: the rootfs files are # owned 1000:1001 while the guest runs as root, so busybox test falls through # to the supplementary-group check and getgroups(2) answers ENOSYS -- a false # result, with `sh: getgroups: Function not implemented' on stderr. Held by # brintos/linux#19. Read the mode out of `ls -l' instead, as 88-p910nd does. check_eq rfkill/alt-mode "-rwxr-xr-x" "$(ls -l "$ALT" 2>/dev/null | cut -c1-10)" # The shipped binary is a real WebAssembly module: \0asm, not \177ELF. The two # cases are asserted from the SAME four bytes and against DIFFERENT constants, # so neither can pass on an artifact the other rejects -- an earlier spelling # of the second looked for the literal "ELF" in `od -An -c' output, where the # characters arrive space-separated, and so passed happily on a native ELF # binary. The native control is what caught it. MAGIC=$(od -An -tx1 -N4 "$ALT" 2>/dev/null | tr -s ' ' | sed 's/^ //;s/ *$//') check_eq rfkill/alt-is-wasm "00 61 73 6d" "$MAGIC" if [ -z "$MAGIC" ]; then bst_notok rfkill/alt-not-elf "could not read the first four bytes of $ALT" elif [ "$MAGIC" = "7f 45 4c 46" ]; then bst_notok rfkill/alt-not-elf "the shipped binary is an ELF object, not a WebAssembly module" else bst_ok rfkill/alt-not-elf; fi # util-linux's rfkill would install its own alternatives target beside ours. # Its absence is why /usr/sbin/rfkill is uncontested here; if it ever appears, # priority 80 beats this recipe's 60 and the link silently changes hands. if [ -e "$UL" ]; then bst_notok rfkill/no-util-linux-target "$UL exists: util-linux-rfkill is now on the image and its ALTERNATIVE_PRIORITY 80 outranks this recipe's 60, so $LINK is no longer guaranteed to be kernel.org's rfkill" else bst_ok rfkill/no-util-linux-target fi # ---------------------------------------------------------------- man page --- check rfkill/man-exists test -f "$MAN" check rfkill/man-nonempty test -s "$MAN" check_eq rfkill/man-is-gzip "1f 8b" "$(od -An -tx1 -N2 "$MAN" 2>/dev/null | tr -s ' ' | sed 's/^ //;s/ *$//')" MANTXT=$(zcat "$MAN" 2>/dev/null || gzip -dc "$MAN" 2>/dev/null) inc rfkill/man-th ".TH RFKILL 8" "$MANTXT" inc rfkill/man-name "tool for enabling and disabling wireless devices" "$MANTXT" inc rfkill/man-synopsis ".SH SYNOPSIS" "$MANTXT" inc rfkill/man-options ".SH OPTIONS" "$MANTXT" inc rfkill/man-commands ".SH COMMANDS" "$MANTXT" inc rfkill/man-cmd-help "Show rfkill's built-in help text" "$MANTXT" inc rfkill/man-cmd-event "Listen for rfkill events" "$MANTXT" inc rfkill/man-cmd-list "List the current state of all available rfkill-using devices" "$MANTXT" inc rfkill/man-cmd-block "Disable the device corresponding to the given index" "$MANTXT" inc rfkill/man-cmd-unblock "Enable the device corresponding to the given index" "$MANTXT" # The man page's identifier vocabulary and the parser's table are asserted # against each other: this list, and the usage line further down that the # parser itself generates by walking rfkill_type_strings[]. inc rfkill/man-identifiers "\"all\", \"wifi\", \"wlan\", \"bluetooth\", \"uwb\"" "$MANTXT" # ----------------------------------------------------------------- version --- # THE DISCRIMINATOR. util-linux's rfkill prints "rfkill from util-linux "; # this one prints "rfkill " and nothing else. If the alternatives link ever # changes hands, these are what goes red. cap rfkill --version rc_is rfkill/version-rc 0 check_eq rfkill/version-stdout "rfkill 1.0" "$OUT" is_empty rfkill/version-stderr "$ERR" check_eq rfkill/version-one-line 1 "$(nlines "$O")" exc rfkill/version-not-util-linux "util-linux" "$OUT" exc rfkill/version-no-from "from" "$OUT" # --version is tested first in main(), so it wins over a following command and # never reaches the device. cap rfkill --version list rc_is rfkill/version-first-rc 0 check_eq rfkill/version-first-stdout "rfkill 1.0" "$OUT" # ---------------------------------------------------- `help' and bare usage --- cap rfkill help rc_is rfkill/help-rc 0 is_empty rfkill/help-stdout "$OUT" inc rfkill/help-stderr "Usage:" "$ERR" check_eq rfkill/help-lines 11 "$(nlines "$E")" HELP=$ERR cap rfkill rc_is rfkill/bare-rc 0 is_empty rfkill/bare-stdout "$OUT" check_eq rfkill/bare-same-as-help "$HELP" "$ERR" # argv0 is echoed verbatim, so this also proves the run came through $LINK's # own name rather than some other path. inc rfkill/usage-argv0 "Usage: rfkill [options] command" "$HELP" inc rfkill/usage-options "Options:" "$HELP" inc rfkill/usage-version-opt " --version show version (1.0)" "$HELP" inc rfkill/usage-commands "Commands:" "$HELP" inc rfkill/usage-cmd-help " help" "$HELP" inc rfkill/usage-cmd-event " event" "$HELP" inc rfkill/usage-cmd-list " list [IDENTIFIER]" "$HELP" inc rfkill/usage-cmd-block " block IDENTIFIER" "$HELP" inc rfkill/usage-cmd-unblock " unblock IDENTIFIER" "$HELP" inc rfkill/usage-identifier "where IDENTIFIER is the index no. of an rfkill switch or one of:" "$HELP" inc rfkill/usage-idx " " "$HELP" # The identifier line is generated by walking rfkill_type_strings[], so it is # the parser's own table printed out -- including both aliases (wlan, and # ultrawideband). inc rfkill/usage-types " all wifi wlan bluetooth uwb ultrawideband wimax wwan gps fm nfc" "$HELP" # util-linux's options must not appear in a usage text this program printed. exc rfkill/usage-no-json "--json" "$HELP" exc rfkill/usage-no-output "--output" "$HELP" exc rfkill/usage-no-noheadings "--noheadings" "$HELP" exc rfkill/usage-no-util-linux "util-linux" "$HELP" # ------------------------------------------ the options this rfkill has NOT --- # Each falls through main()'s final else: usage() on stderr, then return 1. # They are asserted rather than skipped because the ticket named three of them, # and a reader who finds them missing is entitled to know they were checked. for spec in \ "dashdash-help:--help" \ "output:--output" \ "output-eq:--output=NAME" \ "output-short:-o" \ "json:--json" \ "json-short:-J" \ "noheadings:--noheadings" \ "version-eq:--version=x" \ "h-short:-h" do n=${spec%%:*}; o=${spec#*:} cap rfkill "$o" rc_is "rfkill/reject-$n-rc" 1 is_empty "rfkill/reject-$n-stdout" "$OUT" inc "rfkill/reject-$n-usage" "Usage:" "$ERR" done cap rfkill frobnicate rc_is rfkill/unknown-cmd-rc 1 is_empty rfkill/unknown-cmd-stdout "$OUT" inc rfkill/unknown-cmd-usage "Usage:" "$ERR" # block/unblock with no operand fail main()'s `argc > 1' guard and reach that # same else, so they are rc 1 + usage -- NOT the rc 2 a bogus identifier gets. # The pair is what shows the guard is a separate path from the parser. cap rfkill block rc_is rfkill/block-noarg-rc 1 inc rfkill/block-noarg-usage "Usage:" "$ERR" cap rfkill unblock rc_is rfkill/unblock-noarg-rc 1 inc rfkill/unblock-noarg-usage "Usage:" "$ERR" # ------------------------------------------ the identifier parser, rejected --- # rfkill_id_to_type() runs BEFORE any device is opened, so every case here is # device-independent and runs identically on a machine with radios. cap rfkill block zzznosuchtype rc_is rfkill/block-bogus-rc 2 is_empty rfkill/block-bogus-stdout "$OUT" check_eq rfkill/block-bogus-msg "Bogus block argument 'zzznosuchtype'." "$ERR" cap rfkill unblock zzznosuchtype rc_is rfkill/unblock-bogus-rc 2 check_eq rfkill/unblock-bogus-msg "Bogus unblock argument 'zzznosuchtype'." "$ERR" # islower(*s) gates the whole name lookup, so an upper-case name never reaches # the table at all. cap rfkill block WIFI rc_is rfkill/block-upper-rc 2 check_eq rfkill/block-upper-msg "Bogus block argument 'WIFI'." "$ERR" # The match is `strlen(s) == strlen(p->name) && !strcmp(...)', so neither a # prefix nor a suffix of a real name is accepted. Both sides are asserted so a # dropped length test cannot pass. cap rfkill block wif rc_is rfkill/block-prefix-rc 2 cap rfkill block wifi5 rc_is rfkill/block-suffix-rc 2 check_eq rfkill/block-suffix-msg "Bogus block argument 'wifi5'." "$ERR" # An empty operand: *s is '\0', so neither islower nor isdigit fires. cap rfkill block "" rc_is rfkill/block-empty-rc 2 check_eq rfkill/block-empty-msg "Bogus block argument ''." "$ERR" # A leading '-' is neither lower-case nor a digit either. cap rfkill block -1 rc_is rfkill/block-negative-rc 2 # ------------------------------------------ the identifier parser, accepted --- # Driven through `list', which is READ-ONLY -- it opens /dev/rfkill O_RDONLY # and enumerates. `block' would be an equally good parser oracle and would # toggle real radios on a machine that has them, so it is not used here. for t in all wifi wlan bluetooth uwb ultrawideband wimax wwan gps fm nfc; do cap rfkill list "$t" not_bogus "rfkill/type-$t" done # isdigit(*s) takes the index path, whatever the number. for i in 0 7 999999; do cap rfkill list "$i" not_bogus "rfkill/index-$i" done # --------------------------------- `list' rejects, and STILL exits 0 (bug) --- # The discarded return value, asserted BY PAIR -- see the header. If upstream # ever propagates it, the rc case goes red and says so, instead of silently # turning some other case green. cap rfkill list zzznosuchtype check_eq rfkill/list-bogus-msg "Bogus list argument 'zzznosuchtype'." "$ERR" rc_is rfkill/list-bogus-rc-is-0 0 is_empty rfkill/list-bogus-stdout "$OUT" cap rfkill list WIFI check_eq rfkill/list-upper-msg "Bogus list argument 'WIFI'." "$ERR" rc_is rfkill/list-upper-rc-is-0 0 cap rfkill list wifi5 check_eq rfkill/list-suffix-msg "Bogus list argument 'wifi5'." "$ERR" cap rfkill list "" check_eq rfkill/list-empty-msg "Bogus list argument ''." "$ERR" cap rfkill list -1 check_eq rfkill/list-negative-msg "Bogus list argument '-1'." "$ERR" # ------------------------------------------------------ the device, probed --- # /dev/rfkill is the rfkill subsystem's misc device, char 10:242. Its presence # -- not the presence of any switch -- selects the arm. DEV=/dev/rfkill SYS=/sys/class/rfkill if [ -c "$DEV" ]; then ARM=present; else ARM=absent; fi bst_ok "rfkill/probe-device-$ARM" if [ "$ARM" = absent ]; then # ------------------------------------------------ no rfkill subsystem --- # What this kernel actually is. Everything here is the documented failure # path of a tool asked to talk to a subsystem that was never compiled in. check rfkill/dev-absent test ! -e "$DEV" check rfkill/sysfs-absent test ! -d "$SYS" cap rfkill list inc rfkill/list-noopen-msg "Can't open RFKILL control device" "$ERR" inc rfkill/list-noopen-errno "No such file or directory" "$ERR" is_empty rfkill/list-noopen-stdout "$OUT" # The discarded return value on the other of its two paths: rfkill_list() # returned 1 here and `list' still exits 0. This is why the ticket's # "rfkill list exits 0" holds on a kernel with no subsystem at all -- it # is not evidence of a clean empty enumeration. rc_is rfkill/list-noopen-rc-is-0 0 cap rfkill list wifi inc rfkill/list-type-noopen-msg "Can't open RFKILL control device" "$ERR" rc_is rfkill/list-type-noopen-rc-is-0 0 # block/unblock DO propagate the open failure: rc 1 -- not 0, not 2. cap rfkill block wifi rc_is rfkill/block-noopen-rc 1 is_empty rfkill/block-noopen-stdout "$OUT" inc rfkill/block-noopen-msg "Can't open RFKILL control device: No such file or directory" "$ERR" cap rfkill unblock wifi rc_is rfkill/unblock-noopen-rc 1 cap rfkill block 0 rc_is rfkill/block-index-noopen-rc 1 # `event' polls forever on a control device it CAN open. With none it # perrors and returns immediately -- so it is safe to run bare here, and # only here. cap rfkill event rc_is rfkill/event-noopen-rc 0 is_empty rfkill/event-noopen-stdout "$OUT" inc rfkill/event-noopen-msg "Can't open RFKILL control device" "$ERR" NOSUB="no rfkill subsystem on this kernel (CONFIG_RFKILL is not set in arch/wasm32/configs/wasm32_defconfig), so /dev/rfkill does not exist -- the same class of fact 63-tunctl records for CONFIG_TUN" bst_skip rfkill/dev-present "$NOSUB" bst_skip rfkill/sysfs-present "$NOSUB" bst_skip rfkill/list-rc "same: with no control device there is no successful enumeration to give a status for" bst_skip rfkill/list-clean-stderr "same: every list writes a perror line, so a clean stderr is unreachable" bst_skip rfkill/list-empty-enumeration "same: there is nothing to enumerate" bst_skip rfkill/sysfs-name-readable "same: /sys/class/rfkill is not created by a kernel without the subsystem" bst_skip rfkill/list-open-bogus-rc "same: this is the bogus-identifier path WITH the device open; the device-independent half is rfkill/list-bogus-rc-is-0 above" bst_skip rfkill/block-index-open-rc "same: block reaches write(2) only once the control device opens" bst_skip rfkill/event-blocks "same: event returns immediately instead of polling, so the poll loop cannot be exercised" # ------------------------ no device NODE, or no rfkill DRIVER? say which --- # Different findings with different owners: a missing node beside a live # subsystem would be a devtmpfs/populate gap and ours to fix, while a node # that exists and answers ENODEV is the kernel saying the subsystem is not # there. Distinguished from the target side rather than assumed, the way # 63-tunctl does for CONFIG_TUN -- rfkill hardcodes its path and has no -f, # so the probe opens a hand-made node directly instead of through it. node=$tmp/rfkill-node if mknod "$node" c 10 242 >/dev/null 2>&1; then perr=$( (cat "$node") 2>&1 >/dev/null ) case "$perr" in *"No such device"*) bst_ok rfkill/no-driver-not-no-node ;; "") bst_notok rfkill/no-driver-not-no-node "a hand-made 10:242 node OPENED and read: this kernel does have an rfkill subsystem, so the missing $DEV is a device-node gap rather than CONFIG_RFKILL" ;; *) bst_skip rfkill/no-driver-not-no-node "a hand-made 10:242 node answered '$(_bst_1line "$perr")', which is neither ENODEV nor success -- $tmp is mounted nodev, so the open never reached a driver; the kernel .config is the record (CONFIG_RFKILL is not set)" ;; esac rm -f "$node" else bst_skip rfkill/no-driver-not-no-node "mknod is refused here, so 'no node' and 'no driver' cannot be told apart from the target side; the kernel .config is the record (CONFIG_RFKILL is not set)" fi else # ----------------------------------- an rfkill subsystem IS present now --- # The arm the ticket predicted. It has never run on this image; it is # written out in full so that the day CONFIG_RFKILL is turned on the suite # asserts the real behaviour instead of reporting a stale skip. check rfkill/dev-present test -c "$DEV" check rfkill/sysfs-present test -d "$SYS" cap rfkill list rc_is rfkill/list-rc 0 is_empty rfkill/list-clean-stderr "$ERR" # With no switch registered stdout is empty; with switches it is one # "N: : " header per switch plus its two indented lines. if [ -z "$OUT" ]; then bst_ok rfkill/list-empty-enumeration bst_skip rfkill/sysfs-name-readable "no rfkill switch is registered, so there is no /sys/class/rfkill/rfkillN/name to read back" else inc rfkill/list-empty-enumeration "Soft blocked: " "$OUT" inc rfkill/sysfs-name-readable "Hard blocked: " "$OUT" fi # The bogus-identifier path with the device open -- still rc 0, for the # same discarded return value. cap rfkill list zzz-not-a-type-either rc_is rfkill/list-open-bogus-rc 0 # The open succeeds, so block reaches write(2). A bogus INDEX is accepted # by the parser and refused (or ignored) by the kernel; either way rfkill # reports 0, because rfkill_block() perrors a failed write without # propagating it. Opening O_RDWR needs more privilege than the O_RDONLY # `list' above, so a machine where this process cannot get it is a third # outcome and is reported as one rather than as a red -- measured on the # native control, where /dev/rfkill is 0664 root:root and the build # account got "Permission denied" for exactly this case. cap rfkill block 999999 case "$ERR" in *Bogus*) bst_notok rfkill/block-index-open-rc "the parser rejected a numeric index: '$(_bst_1line "$ERR")'" ;; *"Can't open"*) bst_skip rfkill/block-index-open-rc "a control device exists but this process could not open it O_RDWR: $(_bst_1line "$ERR")" ;; *) rc_is rfkill/block-index-open-rc 0 ;; esac SUB="an rfkill control device exists at $DEV, so the no-subsystem path cannot be reached" bst_skip rfkill/dev-absent "$SUB" bst_skip rfkill/sysfs-absent "$SUB" bst_skip rfkill/list-noopen-msg "$SUB" bst_skip rfkill/list-noopen-errno "$SUB" bst_skip rfkill/list-noopen-stdout "$SUB" bst_skip rfkill/list-noopen-rc-is-0 "$SUB" bst_skip rfkill/list-type-noopen-msg "$SUB" bst_skip rfkill/list-type-noopen-rc-is-0 "$SUB" bst_skip rfkill/block-noopen-rc "$SUB" bst_skip rfkill/block-noopen-stdout "$SUB" bst_skip rfkill/block-noopen-msg "$SUB" bst_skip rfkill/unblock-noopen-rc "$SUB" bst_skip rfkill/block-index-noopen-rc "$SUB" bst_skip rfkill/event-noopen-rc "$SUB" bst_skip rfkill/event-noopen-stdout "$SUB" bst_skip rfkill/event-noopen-msg "$SUB" bst_skip rfkill/no-driver-not-no-node "the control device exists, so there is nothing to disambiguate" # event polls forever on a device it can open, so it is only ever run # under a bound -- and only when one is available to impose. if command -v timeout >/dev/null 2>&1; then bst_bound 3 rfkill event >"$O" 2>"$E"; erc=$? check_eq rfkill/event-blocks 124 "$erc" else bst_skip rfkill/event-blocks "no timeout(1) on this image, and rfkill event on a live control device never returns" fi fi rm -rf "$tmp" 2>/dev/null