PERL_SYS_INIT()

Discussion in 'Perl Misc' started by Hallvard B Furuseth, Oct 31, 2011.

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

    --
    Hallvard
     
    Hallvard B Furuseth, Oct 31, 2011
    #1
    1. Advertising

  2. Ben Morrow <> writes:

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

    >
    > 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);

    --
    Hallvard
     
    Hallvard B Furuseth, Oct 31, 2011
    #2
    1. Advertising

  3. Ben Morrow writes:
    > Quoth Hallvard B Furuseth <>:
    >> Ben Morrow <> writes:
    >>> Quoth Hallvard B Furuseth <>:
    >>>> Is PERL_SYS_INIT() as portable as PERL_SYS_INIT3()? (...)
    >>>
    >>> AFAICT they are only different on OS/2, but _INIT3 was introduced in
    >>> 5.6, so you should probably use it anyway. (...)

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

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

    --
    Hallvard
     
    Hallvard B Furuseth, Oct 31, 2011
    #3
  4. On 2011-10-31, Hallvard B Furuseth <> wrote:
    >> 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.


    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
     
    Ilya Zakharevich, Nov 1, 2011
    #4
  5. Hallvard B Furuseth

    Reini Urban Guest

    On 11/01/2011 07:24 AM, Ben Morrow wrote:
    > Quoth Ilya Zakharevich:
    >> On 2011-10-31, Hallvard B Furuseth<> wrote:
    >>>> 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.

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

    >
    > That was what I was intending to imply, but obviously I was unclear :(.
    >
    >> 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.

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

    --
    Reini
     
    Reini Urban, Dec 2, 2011
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page