http://www.perlmonks.org?node_id=1052620

rmahin has asked for the wisdom of the Perl Monks concerning the following question:

Ok perl monks, here is my issue.

Have a script that runs on both windows and unix (sun, aix, linux) platforms. I am trying to do this without using any perl modules not included by default to maintain complete portability. Most machines running this do not have access to the internet, so while far from impossible to install them, its an extra step I'm trying to avoid if possible.

The script is multithreaded, and each thread uses a piped open call to get the outputof a system process. The process I call needs specific environment variables set, so up until now I have been using the format open (my $output, '-|', 'set FOO=BAR& process'); and similar for unix.

This has been working beautifully, but now I would like to be able to kill the process started up from this call programmatically. For this, I need the pid, which the open call so kindly returns. Unfortunately setting the environment variables before hand, causes the open to return the process ID of the shell, and not the actual process.

I need a way to either set the environment variables for the perl script, in a thread-safe fashion, so that I can simply call the process directly in the open, OR...something else?

According to the documentation for unix machines setting the environment variables using %ENV is pretty much a no go when each thread needs different environments, so if there is a way around this, please let me know and it's something I can investigate further.

Here is a simple little script a made to just test this out, minus the threads. Using notepad as the process I call, just because its easy on windows. In it you can see that if you remove the environment variable, and kill the PID printed, notepad closes perfectly fine.

use strict; use warnings; $|++; print "Main PID is " . $$ . "\n"; my $pid = open my $output, '-|', 'set FOO=BAR& notepad.exe' or die $!; print "The PID returned is $pid\n"; print "=========================\n"; while(<$output>){ print $_; } close $output;
Also had a second script, which i used instead of calling notepad so I could see what that actual PID was
$|++; print "My actual PID is " . $$ . "\n"; print "Waiting for you to try and kill me now!\n"; <>;

Thanks in advance for taking a look!

UPDATE: The script in question is a multi-threaded tcp server, that utilizes a thread pool. The server accepts connections, passes work off to a thread pool, and one of the threads in the thread pool is responsible for executing the system command specified, reworking it is not entirely out of the question, but any notion of creating a new thread per connection and joining threads that are finished is not a viable solution. Reasons for this, can be seen found in this thread