Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dup2 on XP #6409

Open
p5pRT opened this issue Mar 31, 2003 · 9 comments
Open

dup2 on XP #6409

p5pRT opened this issue Mar 31, 2003 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Mar 31, 2003

Migrated from rt.perl.org#21776 (status was 'open')

Searchable as RT21776$

@p5pRT
Copy link
Author

p5pRT commented Mar 31, 2003

From mgoland@optonline.net

Hello guys,

I think that perl 5.8 on winXP has a problem with file descripter tables. It fails to properly handle parents STDOUT when I dup2 in the child. Here is my script that runs fine on my FreeBSD box. It properly redirects childs STDOUT to a file , while leaving parents STDOUT to the screen. On an XP box, it redirects both parents and childs STDOUT to a file. Any ideas on how to work around it ??

_____cut script______

#!/usr/bin/perl -w

# $? child error
# $$ pid

use POSIX qw ( :sys_wait_h :unistd_h);
use IO​::Handle;

my $CHILD_SPAWNED=0;
my $CHILD_TO_CREATE=5;
my $MAX_CHILD=3;
my $CHILD_CREATED=0;
$|=1;

#open a file for childs redirection
open(FD,"> ./output") || myerrno();

while( $CHILD_SPAWNED < $CHILD_TO_CREATE ){

print "-------\t\t RUNING $CHILD_CREATED------------\n";

if( $CHILD_CREATED < $MAX_CHILD ){

die "couldnt not spawn​: $!" unless defined ( my $PID=fork() );

$CHILD_CREATED++;
$CHILD_SPAWNED++;

unless( $PID ){
  $|=1;
  dup2(fileno(FD) , fileno(STDOUT) ) || myerrno();
  close(FD);
  $^F=3; #make the redirection get past exec
  print "I am child $$...about to exec\n";

{ exec ("perl count.pl") }; print STDERR "could not exec​: $!";

}

}

$status=waitpid(-1,WNOHANG);

if( $status != 0 ){ #some child has exited
$CHILD_CREATED--;

print "child $status has exited \n";
}

}

print "TOTAL CHILD SPAWNED IS $CHILD_SPAWNED\n";

sub myerrno{
foreach $Val (keys( %!) ){
  print "$Val $!{$Val}\n" if $!{$Val};

}
exit(1);
}

____paste script_____

@p5pRT
Copy link
Author

p5pRT commented Dec 2, 2011

From @jkeenan

On Mon Mar 31 12​:58​:25 2003, mgoland wrote​:

Hello guys,

I think that perl 5.8 on winXP has a problem with file descripter
tables. It fails to properly handle parents STDOUT when I dup2 in
the child. Here is my script that runs fine on my FreeBSD box. It
properly redirects childs STDOUT to a file , while leaving parents
STDOUT to the screen. On an XP box, it redirects both parents and
childs STDOUT to a file. Any ideas on how to work around it ??

In the hope that someone with Win32 access and experience can respond to
this ticket, I have cleaned up the original poster's program somewhat
and am attaching it as 21776.pl. I'm also attaching a simple count.pl
program to serve as the argument for the 'exec' call. On Darwin, the
program appears to execute as the OP intended.

(And, should someone be curious​: No, it didn't get a response when it
was cross-posted on beginners@​perl.org 8-1/2 years ago.)

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Dec 2, 2011

From @jkeenan

count.pl

@p5pRT
Copy link
Author

p5pRT commented Dec 2, 2011

From @jkeenan

21776.pl

@p5pRT
Copy link
Author

p5pRT commented Dec 2, 2011

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Dec 2, 2011

From @tonycoz

On Thu, Dec 01, 2011 at 05​:00​:10PM -0800, James E Keenan via RT wrote​:

On Mon Mar 31 12​:58​:25 2003, mgoland wrote​:

Hello guys,

I think that perl 5.8 on winXP has a problem with file descripter
tables. It fails to properly handle parents STDOUT when I dup2 in
the child. Here is my script that runs fine on my FreeBSD box. It
properly redirects childs STDOUT to a file , while leaving parents
STDOUT to the screen. On an XP box, it redirects both parents and
childs STDOUT to a file. Any ideas on how to work around it ??

In the hope that someone with Win32 access and experience can respond to
this ticket, I have cleaned up the original poster's program somewhat
and am attaching it as 21776.pl. I'm also attaching a simple count.pl
program to serve as the argument for the 'exec' call. On Darwin, the
program appears to execute as the OP intended.

(And, should someone be curious​: No, it didn't get a response when it
was cross-posted on beginners@​perl.org 8-1/2 years ago.)

I suspect what's happening is the *process* stdout is being modified -
fork is emulated on Win32 using threads, so when the child code
modifies stdout it's modified for both the main thread and the child
thread.

C​:\Users\tony>perl -MPOSIX=dup2 -le "if (fork) { print STDERR 'before ', -t STDO
UT; sleep 1; print STDERR 'after ', -t STDOUT; } else { open my $f, '>', 'test.t
xt'; dup2(fileno($f), fileno(*STDOUT)) || die; }"
before 1
after

The workaround is probably IPC​::Open[23].

Tony

@toddr
Copy link
Member

toddr commented Feb 13, 2020

@tonycoz isn't the advice to not fork on windows then?

@toddr
Copy link
Member

toddr commented Feb 13, 2020

No. it is use IPC​::Open[23].

@tonycoz
Copy link
Contributor

tonycoz commented Mar 10, 2020

Ideally we'd provide something vaguely like posix_spawn(), though it would really need to be dual-life (there's POSIX::RT::Spawn but that's very limited, and broken)

@xenu xenu removed the Severity Low label Dec 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants