in reply to Open a second DOS window

There probably isn't a way to do it with one process. However, you can use one process to display whatever is sent through a socket (or named pipe ...) and just connect STDERR to the socket. E.g. here's the program to show the output:
#!perl -w # usage: showerr.pl port use IO::Socket; use strict; $| = 1; $SIG{CHLD} = 'IGNORE'; my $localport = shift; my $socklisten = IO::Socket::INET->new(LocalPort => $localport, Listen => 2, Reuse => 1, Proto => 'tcp') or die "Cannot open sock on $localport: $!\n"; while (my $readport = $socklisten->accept) { print "Accepted new connection at ", scalar(localtime), "\n"; print while <$readport>; print "Connection closed at ", scalar(localtime), "\n"; }
You can start that program independently or you could have the main program start it as below (in which case you would want to take out the outer while loop (replace while with if)):
#!perl -w use IO::Socket; use strict; my $errsocket = "1999"; system("start showerr.pl 1999"); sleep(5); *STDERR = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "localhost:$errsocket", Timeout => 30, ) or die "cannot create socketremote: $!\n"; warn "This is a test"; print STDERR "testing\n"; sleep(10);
Note that there's an awkward sleep() here to wait an undetermined time for the listener to start. This race condition could be fixed, but it might be simpler to just run the showerr program independently first.

Replies are listed 'Best First'.
Re: Re: Open a second DOS window
by Thelonius (Priest) on Oct 08, 2003 at 19:47 UTC
    Here's a better version of my program above, combined into one program and with the race condition fixed:
    #!perl -w use Socket; use IO::Socket; use Getopt::Std; use strict; $| = 1; my %opts; getopts("e:", \%opts); if ($opts{e}) { showerrs($opts{e}); } my $socklisten = IO::Socket::INET->new(LocalPort => 0, Listen => 2, Reuse => 1, Proto => 'tcp') or die "Cannot open socket: $!\n"; my ($port, $myaddr) = sockaddr_in(getsockname($socklisten)); print "port = $port\n"; # Here we start the error process system("start perl $0 -e $port\n"); # should put alarm() timeout around this section if (my $readport = $socklisten->accept) { print "reading from port\n"; chomp(my $portback = <$readport>); print "Connecting to $portback\n"; close($readport); *STDERR = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "localhost:$portback", Timeout => 30, ) or die "cannot create socketremote: $!\n"; } close($socklisten); # warn "this is a test"; sleep(3); print "program exiting\n"; die "I died!!!\n"; sub showerrs { my $port1 = shift; my $socklisten = IO::Socket::INET->new(LocalPort => 0, Listen => 2, Reuse => 1, Proto => 'tcp') or die "Cannot open socket: $!\n"; my ($port, $myaddr) = sockaddr_in(getsockname($socklisten)); my $out = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "localhost:$port1", Timeout => 30, ) or die "cannot create socketremote: $!\n"; print $out "$port\n"; close($out); if (my $readport = $socklisten->accept) { print while <$readport>; } print "Program terminated\n"; # Unless your DOS box is already configured to wait: print "Press Enter to exit ..."; $_ = <>; exit(0); }