From: WanBingjiang Date: Thu, 7 May 2026 01:47:25 +0000 (+0800) Subject: bits: add --fail-width option to reject out-of-range CPU numbers X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=2b49ffe227219adfe18525a5463a105a3bdebfe3;p=thirdparty%2Futil-linux.git bits: add --fail-width option to reject out-of-range CPU numbers By default, cpulist_parse() silently ignores values wider than the cpuset size (fail=0). The new -f/--fail-width flag switches to fail=1, causing bits to error out with "bit list wider than cpuset size" when any CPU number exceeds the --width limit. Signed-off-by: WanBingjiang --- diff --git a/bash-completion/bits b/bash-completion/bits index f68e59aaa..94e15bb69 100644 --- a/bash-completion/bits +++ b/bash-completion/bits @@ -11,7 +11,7 @@ _bits_module() esac case $cur in -*) - OPTS="--version --help --width --mask --grouped-mask --bit --binary --list --expand" + OPTS="--version --help --width --fail-width --mask --grouped-mask --bit --binary --list --expand" COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) return 0 ;; diff --git a/tests/expected/bits/bits-fail-width b/tests/expected/bits/bits-fail-width new file mode 100644 index 000000000..e69de29bb diff --git a/tests/expected/bits/bits-fail-width.err b/tests/expected/bits/bits-fail-width.err new file mode 100644 index 000000000..5274a7d14 --- /dev/null +++ b/tests/expected/bits/bits-fail-width.err @@ -0,0 +1 @@ +bits: error: bit list wider than cpuset size: 1,10000 diff --git a/tests/expected/bits/bits-fail-width.exit_code b/tests/expected/bits/bits-fail-width.exit_code new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/tests/expected/bits/bits-fail-width.exit_code @@ -0,0 +1 @@ +1 diff --git a/tests/expected/bits/bits-truncate b/tests/expected/bits/bits-truncate index e69de29bb..d00491fd7 100644 --- a/tests/expected/bits/bits-truncate +++ b/tests/expected/bits/bits-truncate @@ -0,0 +1 @@ +1 diff --git a/tests/expected/bits/bits-truncate.err b/tests/expected/bits/bits-truncate.err index 5274a7d14..e69de29bb 100644 --- a/tests/expected/bits/bits-truncate.err +++ b/tests/expected/bits/bits-truncate.err @@ -1 +0,0 @@ -bits: error: bit list wider than cpuset size: 1,10000 diff --git a/tests/expected/bits/bits-truncate.exit_code b/tests/expected/bits/bits-truncate.exit_code index 56a6051ca..e69de29bb 100644 --- a/tests/expected/bits/bits-truncate.exit_code +++ b/tests/expected/bits/bits-truncate.exit_code @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/tests/ts/bits/bits b/tests/ts/bits/bits index 3282917a6..d016cda90 100755 --- a/tests/ts/bits/bits +++ b/tests/ts/bits/bits @@ -76,6 +76,10 @@ ts_init_subtest "parse-range" $TS_CMD_BITS -g 50-100 75-150 >> "$TS_OUTPUT" 2>> "$TS_ERRLOG" ts_finalize_subtest +ts_init_subtest "fail-width" +$TS_CMD_BITS --fail-width -l 1,10000 >> $TS_OUTPUT 2>> $TS_ERRLOG +ts_finalize_subtest + ts_init_subtest "parse-invalid" $TS_CMD_BITS -l 1,2,3abc,4 >> $TS_OUTPUT 2>> $TS_ERRLOG ts_finalize_subtest diff --git a/text-utils/bits.1.adoc b/text-utils/bits.1.adoc index 534bcf0e9..28f7b0a23 100644 --- a/text-utils/bits.1.adoc +++ b/text-utils/bits.1.adoc @@ -26,7 +26,7 @@ bits - convert bit masks or lists from/to various formats == SYNOPSIS -*bits* [*-h*] [*-V*] [*-w* _number_] [_mode_] [_mask_|_list_]... +*bits* [*-h*] [*-V*] [*-w* _number_] [*-f*] [_mode_] [_mask_|_list_]... == DESCRIPTION @@ -75,7 +75,12 @@ groups so far. *-w* _number_, *--width* _number_:: The maximum number of bits in the masks handled by *bits*. -The default is *8192*. Any bit larger than this number will be truncated. +The default is *8192*. Any bit larger than this number will be truncated +unless *--fail-width* is specified. + +*-f*, *--fail-width*:: +Fail with an error if the bit list contains values larger than the +*--width* limit. By default, such values are silently ignored. include::man-common/help-version.adoc[] diff --git a/text-utils/bits.c b/text-utils/bits.c index 532de5061..edf1979ba 100644 --- a/text-utils/bits.c +++ b/text-utils/bits.c @@ -30,7 +30,7 @@ #include "xalloc.h" static void parse_mask_or_list(const char *cmdline_arg, - cpu_set_t *all_bits, size_t width) + cpu_set_t *all_bits, size_t width, int fail_width) { cpu_set_t *bits, *copy; char bitwise_op = '|'; @@ -63,7 +63,7 @@ static void parse_mask_or_list(const char *cmdline_arg, if (cpumask_parse(arg, bits, size) < 0) errx(EXIT_FAILURE, _("error: invalid bit mask: %s"), cmdline_arg); } else { - int rc = cpulist_parse(arg, bits, size, 1); + int rc = cpulist_parse(arg, bits, size, fail_width); if (rc == 1) errx(EXIT_FAILURE, _("error: invalid bit list: %s"), cmdline_arg); else if (rc == 2) @@ -231,6 +231,8 @@ static void __attribute__((__noreturn__)) usage(void) fputsln(_(" -w , --width \n" " maximum width of bit masks (default 8192)"), stdout); + fputsln(_(" -f, --fail-width fail if bit list contains values wider than width"), + stdout); fputs(_("\nOutput modes:\n"), stdout); fputsln(_(" -m, --mask display bits as a hex mask value (default)"), @@ -254,9 +256,10 @@ int main(int argc, char **argv) cpu_set_t *bits = NULL; size_t width = 8192; size_t alloc_size; + int fail_width = 0; int c; -#define FLAGS "Vhw:mgble" +#define FLAGS "Vhw:mgblef" static const struct option longopts[] = { { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, @@ -266,6 +269,7 @@ int main(int argc, char **argv) { "binary", no_argument, NULL, 'b' }, { "expand", no_argument, NULL, 'e' }, { "list", no_argument, NULL, 'l' }, + { "fail-width", no_argument, NULL, 'f' }, { NULL, 0, NULL, 0 } }; @@ -298,6 +302,9 @@ int main(int argc, char **argv) if (width == 0) errx(EXIT_FAILURE, _("invalid --width")); break; + case 'f': + fail_width = 1; + break; case 'V': print_version(EXIT_SUCCESS); case 'h': @@ -334,7 +341,7 @@ int main(int argc, char **argv) memset(bits, 0, alloc_size); for (; argc > 0; argc--, argv++) - parse_mask_or_list(*argv, bits, width); + parse_mask_or_list(*argv, bits, width, fail_width); ul_strv_free(stdin_lines);