Peter O'Gorman wrote: > crt_externs.h and _NSGetEnviron works on all released versions of Mac OS X.
Thanks for this info. I'm updating the doc (see below). > The environ symbol is available to every application, it is in the c > startup object crt1.o (on 10.5 crt1.10.5.o), but the static linker, when > set to not allow any undefined symbols (the default) does not know about > it when creating a shared library (because crt1.0 is only added when > creating an executable), so linking will fail with undefined references > to _environ in that case. > > A library which allows undefined symbols (the GNU libtool default) will > not see this problem. Well, there must be something different between MacOS X 10.[34] and 10.5. The cited references mention a problem that cropped up with 10.5, not earlier. Attached you find the test script that I used to verify that both declarations work on 10.3. (I cannot test 10.4 or 10.5.) Bruno --- doc/posix-functions/environ.texi.orig 2008-02-24 17:13:56.000000000 +0100 +++ doc/posix-functions/environ.texi 2008-02-24 17:13:47.000000000 +0100 @@ -23,7 +23,7 @@ #include <crt_externs.h> #define environ (*_NSGetEnviron()) @end smallexample -This works at least on MacOS X 10.3 and newer. +This works at all versions of MacOS X. @end itemize Portability problems not fixed by Gnulib: ================================ fooshared.c ================== #if 0 extern char **environ; #else #include <crt_externs.h> #define environ (*_NSGetEnviron()) #endif char *** environ_addr (void) { return &environ; } =============================================================== ================================= foo.c ======================= #include <stdio.h> #include <unistd.h> extern char ***environ_addr (void); int main () { printf ("%p\n", environ_addr()); { char **env = *environ_addr(); if (env == NULL) printf("env = NULL\n"); else { char *s; for (; (s = *env) && *s; env++) printf ("%s\n", s); } } return 0; } ================================================================ $ libtool --mode=compile gcc -c fooshared.c $ libtool --mode=link gcc -o libfoo.la fooshared.lo $ gcc -c foo.c $ libtool --mode=link gcc -o a.out foo.o libfoo.la $ ./a.out