bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: environ on MacOS X


From: Bruno Haible
Subject: Re: environ on MacOS X
Date: Sun, 24 Feb 2008 17:20:40 +0100
User-agent: KMail/1.5.4

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 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]