Bruno Haible via GNU coreutils General Discussion <[email protected]>
writes:

> This week, this test fails on FreeBSD 14.0:
>
> FAIL: tests/env/env0-from
> =========================
>
> env: environment corrupt; missing value for opaque
> env: cannot unset 'A': Bad address
> --- exp-sorted        2026-08-24 19:26:18.994854000 +0000
> +++ out       2026-08-24 19:26:18.997699000 +0000
> @@ -0,0 +1,4 @@
> +B=old
> +C=operand
> +D=new
> +opaque
> env: cannot unset '': Invalid argument
> env: cannot unset 'A=B': Invalid argument
> env: cannot unset '': Invalid argument
> env: cannot unset 'A=B': Invalid argument
> FAIL tests/env/env0-from.sh (exit status: 1)

Thats annoying. FreeBSD getenv, putenv, and friends just give up upon
seeing an environment variable without a value, instead of continuing
like everyone else [1].

I don't like the attached patch, but I don't see an alternative...

Collin

[1] 
https://github.com/freebsd/freebsd-src/blob/9496457f230f933afa78b0a60295d59828bff08c/lib/libc/stdlib/getenv.c#L354-L364

>From 10f7c1cea365e49797128f1719b0b75d291f13b4 Mon Sep 17 00:00:00 2001
Message-ID: <10f7c1cea365e49797128f1719b0b75d291f13b4.1787623079.git.collin.fu...@gmail.com>
From: Collin Funk <[email protected]>
Date: Mon, 24 Aug 2026 18:56:28 -0700
Subject: [PATCH] tests: env: adjust test to freebsd behavior

* tests/env/env0-from.sh: Don't test environment variables without a
value on FreeBSD.
---
 tests/env/env0-from.sh | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/tests/env/env0-from.sh b/tests/env/env0-from.sh
index 9e54e7e47..00faeadf9 100755
--- a/tests/env/env0-from.sh
+++ b/tests/env/env0-from.sh
@@ -79,8 +79,11 @@ compare exp out || fail=1
 # its process environment block, and retains the system putenv merge path.
 # Generate expected environments through an exec, since some systems add
 # entries such as __CF_USER_TEXT_ENCODING when starting a process.
+# FreeBSD and it's derivatives setenv, putenv, etc. choke if given an
+# environment variable without a value.
 case $host_os in
   mingw* | windows*) ;;
+  freebsd* | dragonfly* | midnightbsd*) ;;
   *)
     printf 'A=old1\0opaque\0A=old2\0B=old\0' >base \
       || framework_failure_
@@ -113,20 +116,25 @@ case $host_os in
     ;;
 esac
 
-# With -i, preserve all entries byte-for-byte, including duplicate names,
-# entries without '=', and empty entries.
-printf 'A=first\0opaque\0A=last\0\0=value\0B=\0' >raw \
-  || framework_failure_
-env -i --env0-from=raw -0 >out || fail=1
-compare raw out || fail=1
-env -0 --env0-from=raw - >out || fail=1
-compare raw out || fail=1
-
-# Apply -u and command-line assignments without normalizing other entries.
-printf 'opaque\0\0=value\0B=changed\0C=new\0' >exp \
-  || framework_failure_
-env -i --env0-from=raw -u A -0 B=changed C=new >out || fail=1
-compare exp out || fail=1
+case $host_os in
+  freebsd* | dragonfly* | midnightbsd*) ;;
+  *)
+    # With -i, preserve all entries byte-for-byte, including duplicate names,
+    # entries without '=', and empty entries.
+    printf 'A=first\0opaque\0A=last\0\0=value\0B=\0' >raw \
+      || framework_failure_
+    env -i --env0-from=raw -0 >out || fail=1
+    compare raw out || fail=1
+    env -0 --env0-from=raw - >out || fail=1
+    compare raw out || fail=1
+
+    # Apply -u and command-line assignments without normalizing other entries.
+    printf 'opaque\0\0=value\0B=changed\0C=new\0' >exp \
+      || framework_failure_
+    env -i --env0-from=raw -u A -0 B=changed C=new >out || fail=1
+    compare exp out || fail=1
+    ;;
+esac
 
 # Appending beyond the loaded vector must update environ after reallocating.
 printf 'A=one\0' >one || framework_failure_
@@ -165,6 +173,7 @@ case $host_os in
     printf '\0' >invalid || framework_failure_
     returns_ 125 env --env0-from=invalid >out 2>err || fail=1
     ;;
+  freebsd* | dragonfly* | midnightbsd*) ;;
   *)
     printf 'A=file1\0opaque\0\0A=file2\0B=new\0' >mixed \
       || framework_failure_
-- 
2.55.0

Reply via email to