]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
bits: add --fail-width option to reject out-of-range CPU numbers
authorWanBingjiang <wanbingjiang@webray.com.cn>
Thu, 7 May 2026 01:47:25 +0000 (09:47 +0800)
committerWanBingjiang <wanbingjiang@webray.com.cn>
Thu, 7 May 2026 01:52:16 +0000 (09:52 +0800)
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 <wanbingjiang@webray.com.cn>
bash-completion/bits
tests/expected/bits/bits-fail-width [new file with mode: 0644]
tests/expected/bits/bits-fail-width.err [new file with mode: 0644]
tests/expected/bits/bits-fail-width.exit_code [new file with mode: 0644]
tests/expected/bits/bits-truncate
tests/expected/bits/bits-truncate.err
tests/expected/bits/bits-truncate.exit_code
tests/ts/bits/bits
text-utils/bits.1.adoc
text-utils/bits.c

index f68e59aaa4b5310dc649a533ae7b469429912b35..94e15bb6983a28c2d1a8ee4d441f0b0b17d70150 100644 (file)
@@ -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 (file)
index 0000000..e69de29
diff --git a/tests/expected/bits/bits-fail-width.err b/tests/expected/bits/bits-fail-width.err
new file mode 100644 (file)
index 0000000..5274a7d
--- /dev/null
@@ -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 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 100644 (file)
@@ -0,0 +1 @@
+1
index 5274a7d147a5f7aa77838f9b879a92cb9434bcbb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1 +0,0 @@
-bits: error: bit list wider than cpuset size: 1,10000
index 56a6051ca2b02b04ef92d5150c9ef600403cb1de..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1 +0,0 @@
-1
\ No newline at end of file
index 3282917a6c9a2447e76104b1134713c7d6de8159..d016cda9035f00e50a1476f86d7d6f785e2e07da 100755 (executable)
@@ -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
index 534bcf0e976260a545ee350aa84a1af2266ec0cf..28f7b0a236b80e9a4e875043fe38051aa4b303c0 100644 (file)
@@ -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[]
 
index 532de50613630f8c921c90611a17a97ee604b413..edf1979ba0a1b2538317bbbf9071b8c9af83567d 100644 (file)
@@ -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 <num>, --width <num>\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);