in reply to Re^16: Using STDIN after exec() with ActiveState Perl
in thread Using STDIN after exec() with ActiveState Perl

Update: Ok, so can't use a BEGIN block...

On Windows, exec is simulated in a strange way. Apparently, it's creating a new process and exiting the caller before the new process exits.

(Update 2: On Linux, exec does not start a new process, it loads a new executable into the calling process. From the command shell's point of view, the process it launched is still running, so it's not trying to read STDIN.)

Your problem with system is that you need to exit after system returns:

use warnings; use strict; use Module::Load; if(! $ENV{SPRING_WRITEDIR}) { $ENV{SPRING_WRITEDIR}='E:\\test'; system {$^X} ($^X,$0); exit; }

Yes, you will have 2 Perl processes where you had 1, but one of those will be idle while waiting on the other to exit.

Please try:

use warnings; use strict; BEGIN { $ENV{SPRING_WRITEDIR}='E:\\test'; $ENV{PATH}="E:\\springrts;$ENV{PATH}"; } use Module::Load; load("PerlUnitSync"); PerlUnitSync::Init(0,0); my $writeDir=PerlUnitSync::GetWritableDataDirectory(); print "writeDir=$writeDir\n";

This will set the environment before Module::Load is loaded.

Replies are listed 'Best First'.
Re^18: Using STDIN after exec() with ActiveState Perl
by Yaribz (Beadle) on Jun 23, 2015 at 08:59 UTC
    Thanks for looking into this. The problem is that my script must be able to modify the environment variables as many times as needed during its execution, which would lead to a growing number of idle perl processes with this solution.

      Thanks for looking into this. The problem is that my script must be able to modify the environment variables as many times as needed during its execution, which would lead to a growing number of idle perl processes with this solution.

      I would argue you must be missing an API call that exists and does the same thing directly, no relying on %ENV

        You're totally right, cf Re^20: Using STDIN after exec() with ActiveState Perl

        edit: oh actually I guess you meant an API call in the dynamic library I load, which would allow me to avoid relying on environment variables. Yes you're right, unfortunately there is no such API function to set the write directory (only data directories). And if it was added now, I wouldn't be able to use it anyway since I have to maintain backward compatibility with older versions of this library.

      Are there several processes running in parallel that use different version of the library?

      If they are not parallel, instead of exiting after system returns, loop back up and determine the next set of ENV variable settings for the next run via system.

      If several parallel sequential runs, just run as many "top level" instances of the top level Perl program as needed.

        Several instances are usually running in parallel and might be using different versions of the library, yes.

        The next set of ENV variables would be known by the child process but not the idle "top level" one, so I would have to pass back the info to the parent process. It would be a possible workaround indeed, but I prefer the "simplicity" of the workaround I'm using right now which simply avoids exec/system when running on Windows (cf Re^20: Using STDIN after exec() with ActiveState Perl).

        But thanks again nonetheless.