Page MenuHome GnuPG

libgpg-error 1.50 build issue (spawn-posix.c:345:5: error: use of undeclared identifier 'environ')
Open, NormalPublic

Description

While updating the MacPorts Portfile to libgpg-error 1.50, I ran into the following error:

:info:build /bin/sh ../libtool  --tag=CC   --mode=compile /usr/bin/clang -DHAVE_CONFIG_H -I. -I..  -DLOCALEDIR=\"/opt/local/share/locale\" -I/opt/local/include -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk  -pipe -Os -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -arch arm64 -Wall -Wpointer-arith -MT libgpg_error_la-spawn-posix.lo -MD -MP -MF .deps/libgpg_error_la-spawn-posix.Tpo -c -o libgpg_error_la-spawn-posix.lo `test -f 'spawn-posix.c' || echo './'`spawn-posix.c
:info:build spawn-posix.c:345:5: error: use of undeclared identifier 'environ'
:info:build     environ = act->environ;
:info:build     ^

macOS 14.5 23F79 arm64
Xcode 15.4 15F31d
Apple clang version 15.0.0 (clang-1500.3.9.4)

Full log attached

P.S. Sorry Werner! After more closely examining the diff between 1.49 and 1.50, it looks like spawn-posix.c got a major rewrite, rather than a small change in variable names. Context!

Event Timeline

I encountered this also on macOS. Apparently, Apple does not provide an declaration for environ, in contradiction to the manual page for execv.

werner changed the task status from Open to Testing.Jun 20 2024, 12:05 PM
werner added a subscriber: werner.

Frankly, having environ declared in unistd.h is a glibc convenience and other systems likey don't have it. easy to fix, though.

werner claimed this task.
werner triaged this task as Normal priority.
werner added a project: MacOS.
werner added a project: gpgrt.

It looks like various flavors of BSD (including macOS just declare environ when needed): environ -- user environment Note: this is a very old MacOS X man page, however the current version is from 2003, and has the same Synopsis.

Quick workaround (should wrap it in the proper #if clauses):

--- src/spawn-posix.c.orig	2024-06-19 02:33:41
+++ src/spawn-posix.c	2024-06-20 10:01:26
@@ -57,6 +57,7 @@
 
 #include "gpgrt-int.h"
 
+extern char **environ;
 
 /* Definition for the gpgrt_spawn_actions_t.  Note that there is a
  * different one for Windows.  */

While the above patch worked for MacOS 10.8 and above, MacPorts CI shows a second error for older MacOS versions:

libtool: link: /usr/bin/clang -dynamiclib  -o .libs/libgpg-error.0.dylib  .libs/libgpg_error_la-posix-lock.o .libs/libgpg_error_la-posix-thread.o .libs/libgpg_error_la-spawn-posix.o .libs/libgpg_error_la-init.o .libs/libgpg_error_la-version.o .libs/libgpg_error_la-estream.o .libs/libgpg_error_la-estream-printf.o .libs/libgpg_error_la-strsource.o .libs/libgpg_error_la-strerror.o .libs/libgpg_error_la-code-to-errno.o .libs/libgpg_error_la-code-from-errno.o .libs/libgpg_error_la-visibility.o .libs/libgpg_error_la-sysutils.o .libs/libgpg_error_la-stringutils.o .libs/libgpg_error_la-syscall-clamp.o .libs/libgpg_error_la-logging.o .libs/libgpg_error_la-b64dec.o .libs/libgpg_error_la-b64enc.o .libs/libgpg_error_la-argparse.o   -L/opt/local/lib -lintl  -Os -arch x86_64 -Wl,-headerpad_max_install_names -arch x86_64 -Wl,-framework -Wl,CoreFoundation   -install_name  /opt/local/lib/libgpg-error.0.dylib -compatibility_version 38 -current_version 38.0 -Wl,-single_module
Undefined symbols for architecture x86_64:
  "_environ", referenced from:
      _my_exec in libgpg_error_la-spawn-posix.o
     (maybe you meant: _gpgrt_spawn_actions_set_environ, __gpgrt_spawn_actions_set_environ )
ld: symbol(s) not found for architecture x86_64
gniibe added a subscriber: gniibe.

Use of execve is better (avoiding use of environ).

diff --git a/src/spawn-posix.c b/src/spawn-posix.c
index 96f1536..8a14724 100644
--- a/src/spawn-posix.c
+++ b/src/spawn-posix.c
@@ -57,9 +57,6 @@
 
 #include "gpgrt-int.h"
 
-/* (Only glibc's unistd.h declares this iff _GNU_SOURCE is used.)  */
-extern char **environ;
-
 
 /* Definition for the gpgrt_spawn_actions_t.  Note that there is a
  * different one for Windows.  */
@@ -344,9 +341,6 @@ my_exec (const char *pgmname, const char *argv[], gpgrt_spawn_actions_t act)
   /* Close all other files.  */
   _gpgrt_close_all_fds (3, act->except_fds);
 
-  if (act->environ)
-    environ = act->environ;
-
   if (act->atfork)
     act->atfork (act->atfork_arg);
 
@@ -354,7 +348,11 @@ my_exec (const char *pgmname, const char *argv[], gpgrt_spawn_actions_t act)
   if (pgmname == NULL)
     return 0;
 
-  execv (pgmname, (char *const *)argv);
+  if (act->environ)
+    execve (pgmname, (char *const *)argv, act->environ);
+  else
+    execv (pgmname, (char *const *)argv);
+    
   /* No way to print anything, as we have may have closed all streams. */
   _exit (127);
   return -1;