PERL_SYS_INIT()

  • Thread starter Hallvard B Furuseth
  • Start date
H

Hallvard B Furuseth

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.

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.
 
H

Hallvard B Furuseth

Ben Morrow said:
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.)

Sounds like it's safest to use INIT when available and INIT3 otherwise,
then. That leaves as much as possible of the work to Perl.
(...) 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).

Yuck. I'm fixing some apparently untested code, and I won't be testing
my fix either on any of those systems:-( I'll try this for now, for the
application's set-up code:

char *embedding[] = { "", "-e", "0", NULL }; /*added NULL just in case*/
char **argv = embedding, **env = NULL;
int argc = 3;

#ifdef PERL_SYS_INIT
PERL_SYS_INIT(&argc, &argv);
#elif defined PERL_SYS_INIT3
env = environ;
PERL_SYS_INIT3(&argc, &argv, &env);
#endif

my_perl = perl_alloc();
perl_construct(my_perl);
#ifdef PERL_EXIT_DESTRUCT_END
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
#endif
perl_parse(my_perl, my_xs_init, argc, argv, env);
perl_run(my_perl);
 
H

Hallvard B Furuseth

Ben said:
_INIT is always available (at least, in all versions of perl which
support embedding). (...)

I'll stick to INIT and drop INIT3 and env then, that'll equivalent to my
posted code. I misunderstood - I thought you meant INIT3 was introduced
earlier, not later.

Thank you for your help.
 
I

Ilya Zakharevich

Sounds like it's safest to use INIT when available and INIT3 otherwise,
then. That leaves as much as possible of the work to Perl.

The opposite. INIT is not supported. If it works, then only
accidentally.

env MUST be passed as the third argument to INIT3 (although it might
be coded to do something reasonable when the third argument is NULL -
do not have the source with me now to check.

Hope this helps,
Ilya
 
R

Reini Urban

Quoth Ilya Zakharevich:

That was what I was intending to imply, but obviously I was unclear :(.


The only case where INIT3 doesn't simply call INIT is OS/2, which
properly uses the global environ when passed a NULL env pointer
(complete with 'yuck' comments, I presume from you :)).

The Win32 case *ought* to use INIT3, but instead pokes values into the
environment using both CRTL's putenv and Win32's SetEnvironmentVariable,
so for portable code relying on the semantics of INIT3 (that is, trying
to pass anything other than the true global environ pointer) is
currently a bad idea.

So: Hallvard is currently right that INIT is more reliable, in practice.
In principle, it would be better if this were not the case, but I
suspect given the state of the Win32 code it isn't likely to change. The
IMP_SYS stuff just relies too much on using Win32 calls to affect the
real process environment.

Your code needs to support $ENV{bla} = "bla", so you must use INIT3.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top