From 162ddbe9720bec65af1373de1fa01036e9d3a93c Mon Sep 17 00:00:00 2001 From: Arun Bhattacharya Date: Wed, 12 Aug 2026 15:12:25 +0100 Subject: [PATCH] uname: add -A,--all-labeled to print labeled lines * doc/coreutils.texi (uname invocation): Describe -A,--all-labeled. * src/uname.c (main): Accept new option. (print_element): Also output label if enabled. * tests/misc/uname-labeled.sh: Add a new test. * tests/local.mk: Reference the new test. * NEWS: Mention the new feature. Link: https://github.com/coreutils/coreutils/issues/313 --- NEWS | 2 ++ doc/coreutils.texi | 5 ++++ src/uname.c | 59 ++++++++++++++++++++++++++----------- tests/local.mk | 1 + tests/misc/uname-labeled.sh | 44 +++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 18 deletions(-) create mode 100755 tests/misc/uname-labeled.sh diff --git a/NEWS b/NEWS index 2a9a13d97..17a6333d3 100644 --- a/NEWS +++ b/NEWS @@ -75,6 +75,8 @@ GNU coreutils NEWS -*- outline -*- stat -f -c%T now reports the file system type, and tail -f uses inotify for this file system. + uname adds the -A,--all-labeled option to label all output, one item per line. + ** Changes in behavior 'env' and 'printenv' now quote printed environment variables honoring the diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 769f1930c..f72c169bd 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -16947,6 +16947,11 @@ The program accepts the following options. Also see @ref{Common options}. Print all of the below information, except omit the processor type and the hardware platform name if they are unknown. +@optItem{uname,-A,} +@optItemx{uname,--all-labeled,} +Like @option{-a}, print all of the below information, +in a vertical, labeled format: @var{label}: @var{value}. + @optItem{uname,-i,} @optItemx{uname,--hardware-platform,} @cindex implementation, hardware diff --git a/src/uname.c b/src/uname.c index 5f7a35dd6..d41dabe49 100644 --- a/src/uname.c +++ b/src/uname.c @@ -79,9 +79,12 @@ /* Operating system. */ #define PRINT_OPERATING_SYSTEM 128 +static bool labeled = false; + static struct option const uname_long_options[] = { {"all", no_argument, NULL, 'a'}, + {"all-labeled", no_argument, NULL, 'A'}, {"kernel-name", no_argument, NULL, 's'}, {"sysname", no_argument, NULL, 's'}, /* Obsolescent. */ {"nodename", no_argument, NULL, 'n'}, @@ -122,6 +125,10 @@ Print certain system information. With no OPTION, same as -s.\n\ oputs (_("\ -a, --all print all information, in the following order,\n\ except omit -p and -i if unknown\n\ +")); + oputs (_("\ + -A, --all-labeled print all information, one labeled field per line,\n\ + except omit -p and -i if unknown\n\ ")); oputs (_("\ -s, --kernel-name print the kernel name\n\ @@ -167,13 +174,20 @@ Print machine architecture.\n\ printed. */ static void -print_element (char const *element) +print_element (char const *element, char const *label) { - static bool printed; - if (printed) - putchar (' '); - printed = true; - fputs (element, stdout); + if (labeled) + { + printf ("%s: %s\n", label, element); + } + else + { + static bool printed; + if (printed) + putchar (' '); + printed = true; + fputs (element, stdout); + } } /* Print ELEMENT, preceded by a space if something has already been @@ -181,7 +195,9 @@ print_element (char const *element) value instead of ELEMENT. */ static void -print_element_env (char const *element, MAYBE_UNUSED char const *envvar) +print_element_env (char const *element, + MAYBE_UNUSED char const *envvar, + char const *label) { #ifdef __APPLE__ if (envvar) @@ -191,7 +207,7 @@ print_element_env (char const *element, MAYBE_UNUSED char const *envvar) element = val; } #endif - print_element (element); + print_element (element, label); } @@ -224,7 +240,7 @@ decode_switches (int argc, char **argv) } else { - while ((c = getopt_long (argc, argv, "asnrvmpio", + while ((c = getopt_long (argc, argv, "asnrvmpioA", uname_long_options, NULL)) != -1) { @@ -232,6 +248,12 @@ decode_switches (int argc, char **argv) { case 'a': toprint = UINT_MAX; + labeled = false; + break; + + case 'A': + toprint = UINT_MAX; + labeled = true; break; case 's': @@ -316,15 +338,15 @@ main (int argc, char **argv) error (EXIT_FAILURE, errno, _("cannot get system name")); if (toprint & PRINT_KERNEL_NAME) - print_element_env (name.sysname, "UNAME_SYSNAME"); + print_element_env (name.sysname, "UNAME_SYSNAME", _("Kernel name")); if (toprint & PRINT_NODENAME) - print_element_env (name.nodename, "UNAME_NODENAME"); + print_element_env (name.nodename, "UNAME_NODENAME", _("Node name")); if (toprint & PRINT_KERNEL_RELEASE) - print_element_env (name.release, "UNAME_RELEASE"); + print_element_env (name.release, "UNAME_RELEASE", _("Kernel release")); if (toprint & PRINT_KERNEL_VERSION) - print_element_env (name.version, "UNAME_VERSION"); + print_element_env (name.version, "UNAME_VERSION", _("Kernel version")); if (toprint & PRINT_MACHINE) - print_element_env (name.machine, "UNAME_MACHINE"); + print_element_env (name.machine, "UNAME_MACHINE", _("Machine")); } if (toprint & PRINT_PROCESSOR) @@ -358,7 +380,7 @@ main (int argc, char **argv) } #endif if (! (toprint == UINT_MAX && element == unknown)) - print_element (element); + print_element (element, _("Processor")); } if (toprint & PRINT_HARDWARE_PLATFORM) @@ -383,13 +405,14 @@ main (int argc, char **argv) } #endif if (! (toprint == UINT_MAX && element == unknown)) - print_element (element); + print_element (element, _("Hardware platform")); } if (toprint & PRINT_OPERATING_SYSTEM) - print_element (HOST_OPERATING_SYSTEM); + print_element (HOST_OPERATING_SYSTEM, _("Operating system")); - putchar ('\n'); + if (!labeled) + putchar ('\n'); return EXIT_SUCCESS; } diff --git a/tests/local.mk b/tests/local.mk index a6ee702e5..33abb9d72 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -187,6 +187,7 @@ all_tests = \ tests/misc/responsive.sh \ tests/misc/traversal-missing.sh \ tests/misc/tty-quoting.sh \ + tests/misc/uname-labeled.sh \ tests/misc/warning-errors.sh \ tests/misc/write-errors.sh \ tests/tail/basic-seek.sh \ diff --git a/tests/misc/uname-labeled.sh b/tests/misc/uname-labeled.sh new file mode 100755 index 000000000..fe6107faa --- /dev/null +++ b/tests/misc/uname-labeled.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# Test -A / --all-labeled option of uname + +# Copyright (C) 2026 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ uname + +# Test basic -A / --all-labeled functionality +uname -A > out || fail=1 +uname --all-labeled > out_long || fail=1 +compare out out_long || fail=1 + +# Check that the output format has labels and values +grep '^Kernel name: ' out || fail=1 +grep '^Node name: ' out || fail=1 +grep '^Kernel release: ' out || fail=1 +grep '^Kernel version: ' out || fail=1 +grep '^Machine: ' out || fail=1 +# processor and hardware-platform may be omitted if unknown +grep '^Operating system: ' out || fail=1 + +# Ensure that standard uname output (e.g. uname -a) is unchanged +uname -a > out_std || fail=1 +# out_std must be a single line and not contain the labels +test $(wc -l < out_std) -eq 1 || fail=1 +grep -F 'Kernel name:' out_std && fail=1 +grep -F 'Node name:' out_std && fail=1 +grep -F 'Kernel release:' out_std && fail=1 + +Exit $fail