Hello,

This patch adds support for the -A option to uname, as proposed in
https://github.com/coreutils/coreutils/issues/313.

I have updated the docs and tests and also performed syntax-check.

This is my first contribution to GNU Coreutils, I would appreciate
any feedback or suggestions for improvement.

Thanks,
Arun

---
 doc/coreutils.texi          |  7 +++++
 src/uname.c                 | 59 ++++++++++++++++++++++++++-----------
 tests/local.mk              |  1 +
 tests/misc/uname-labeled.sh | 43 +++++++++++++++++++++++++++
 4 files changed, 92 insertions(+), 18 deletions(-)
 create mode 100755 tests/misc/uname-labeled.sh

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 5cc831f84..1ddc1d101 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -16862,6 +16862,13 @@ 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,}
+Print all of the below information in a vertical, labeled format:
+@var{label} : @var{value}.
+Like @option{-a}, the processor type and hardware platform name are omitted
+if they are unknown.
+
 @optItem{uname,-i,}
 @optItemx{uname,--hardware-platform,}
 @cindex implementation, hardware
diff --git a/src/uname.c b/src/uname.c
index 5f7a35dd6..df7e76530 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", _("nodename"));
       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 e2afbe134..7817edccf 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -290,6 +290,7 @@ all_tests =                    \
   tests/mktemp/mktemp.pl            \
   tests/mktemp/write-error.sh            \
   tests/misc/arch.sh                \
+  tests/misc/uname-labeled.sh            \
   tests/pr/bounded-memory.sh            \
   tests/pr/options.sh                \
   tests/pr/pr-tests.pl                \
diff --git a/tests/misc/uname-labeled.sh b/tests/misc/uname-labeled.sh
new file mode 100755
index 000000000..4132d7f46
--- /dev/null
+++ b/tests/misc/uname-labeled.sh
@@ -0,0 +1,43 @@
+#!/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 <https://www.gnu.org/licenses/>.
+
+. "${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 "^nodename : " 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 should not contain " : "
+if grep " : " out_std; then
+  fail=1
+fi
+
+Exit $fail
--
2.54.0


Reply via email to