On 03/08/2026 06:10, Collin Funk wrote:
The example patch I sent earlier was incorrect, since it quoted the
variable and its value together. This fixes that, and also makes it
trivial to get the same behavior in 'env'.

+#ifndef PRINTENV_H
+# define PRINTENV_H 1
+
+static inline void
+print_envvar (char const *entry, char terminator, bool quoted)
+{
+  if (! quoted)
+    {
+      fputs (entry, stdout);
+      putchar (terminator);
+    }
+  else
+    {
+      idx_t const entry_len = strlen (entry);
+      char const *equal = memchr (entry, '=', entry_len);
+
+      /* If the parent process manipulates ENVIRON directly, it is possible
+         that an entry does not contain an equal sign.  */
+      idx_t const var_len = equal ? equal - entry : entry_len;
+      fputs (quoteN_mem (entry, var_len), stdout);
+
+      if (equal)
+        {
+          putchar ('=');
+          char const *val = equal + 1;
+          idx_t const val_len = entry_len - (val - entry);
+          /* Prefer "VAR=" over "VAR=''".  */
+          if (0 < val_len)
+            fputs (quoteN_mem (val, val_len), stdout);
+        }
+      putchar (terminator);
+    }
+}
+
+#endif

Nice. So this avoids quoting the foo= portion unless necessary.
Minor nit, is one could have a single putchar (terminator) at the end.

diff --git a/tests/misc/tty-quoting.sh b/tests/misc/tty-quoting.sh
index a0dc1d4b8..603a3fa8a 100755
--- a/tests/misc/tty-quoting.sh
+++ b/tests/misc/tty-quoting.sh
@@ -20,6 +20,7 @@
  print_ver_ basename dirname du ls readlink realpath printf test
  require_strace_ ioctl

This should probably list printenv

thanks!
Padraig

Reply via email to