Quoth Hallvard B Furuseth <
h.b.fu...@usit.uio.no>:
> Is PERL_SYS_INIT() as portable as PERL_SYS_INIT3()? It is not
> documented in the manpages. I'm wondering if I should use that or
> pass a pointer to the possibly less portable extern char **environ;
> since proto.h says __attribute__nonnull__ for env.
AFAICT they are only different on OS/2, but _INIT3 was introduced in
5.6, so you should probably use it anyway. (They probably *ought* to be
different at least on Win32, as well, since the Win32 init code affects
the environment, but currently they aren't.)
> I'm looking at a program doing roughly
>
> char *embedding[] = { "", "-e", "0" }, **argv = embedding;
> int argc = 3;
> PERL_SYS_INIT3(&argc, &argv, (char ***)NULL);
> ...
> perl_parse(my_perl, xs_init, 3, argv, NULL);
>
> Can PERL_SYS_INIT(,&argv) change argv? If so, how, and should
> the remaining program pass the unchanged 'embedding' or the
> changed 'argv' to perl_parse()? man perlembed shows both variants.
Perl embedding is not very well tested. There are some notable cases
that work well, like mod_perl, but they all end up knowing more about
the perl guts than is documented in perlembed. About the only way to be
safe is to look at perlmain.c and do what that does, though even that
isn't always possible since it uses symbols that aren't exported on all
platforms. From my experiments with it all I can recommend is to try
things until you find something that works, and to expect to have to make
minor fixes if you upgrade to a new major version of perl.
That said, I believe the correct answer is you should pass the real
environment to _INIT3 (whether from the third arg of main or from the
global environ), and you should pass the argv pointer you passed to
_INIT3 to perl_parse. On some systems (VMS, OS/2) _INIT3 will modify the
passed-in argv; on some systems (Win32, at least) it will modify the
global environment and assume this will affect what perl_parse sees
(ignoring the env pointer passed to _INIT3).
Ben