3 # tests for both real and emulated fork()
8 require Config; import Config;
9 unless ($Config{'d_fork'} or $Config{'d_pseudofork'}) {
10 print "1..0 # Skip: no fork\n";
13 $ENV{PERL5LIB} = "../lib";
18 print "1..0 # Skip: fork/status problems on MPE/iX\n";
25 @prgs = split "\n########\n", <DATA>;
26 print "1..", scalar @prgs, "\n";
28 $tmpfile = tempfile();
31 $CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : (($^O eq 'NetWare') ? 'perl -e "print <>"' : 'cat'));
38 my($prog,$expected) = split(/\nEXPECT\n/, $_);
39 $expected =~ s/\n+$//;
40 # results can be in any order, so sort 'em
41 my @expected = sort split /\n/, $expected;
42 open TEST, ">$tmpfile" or die "Cannot open $tmpfile: $!";
43 print TEST $prog, "\n";
44 close TEST or die "Cannot close $tmpfile: $!";
46 if ($^O eq 'MSWin32') {
47 $results = `.\\perl -I../lib $switch $tmpfile 2>&1`;
49 elsif ($^O eq 'NetWare') {
50 $results = `perl -I../lib $switch $tmpfile 2>&1`;
53 $results = `./perl $switch $tmpfile 2>&1`;
57 $results =~ s/at\s+$::tempfile_regexp\s+line/at - line/g;
58 $results =~ s/of\s+$::tempfile_regexp\s+aborted/of - aborted/g;
59 # bison says 'parse error' instead of 'syntax error',
60 # various yaccs may or may not capitalize 'syntax'.
61 $results =~ s/^(syntax|parse) error/syntax error/mig;
62 $results =~ s/^\n*Process terminated by SIG\w+\n?//mg
64 my @results = sort split /\n/, $results;
65 if ( "@results" ne "@expected" ) {
66 print STDERR "PROG: $switch\n$prog\n";
67 print STDERR "EXPECTED:\n$expected\n";
68 print STDERR "GOT:\n$results\n";
71 print "ok ", ++$i, "\n";
78 if ($result = (kill 9, $cid)) {
82 print "not ok 2 $result\n";
84 sleep 1 if $^O eq 'MSWin32'; # avoid WinNT race bug
97 print "not " unless kill 'INT', $cid;
101 # XXX On Windows the default signal handler kills the
102 # XXX whole process, not just the thread (pseudo-process)
103 $SIG{INT} = sub { exit };
114 print "iteration $i start\n";
118 print "iteration $i parent\n";
121 print "iteration $i child\n";
125 print "pid $$ failed to fork\n";
128 while ($i++ < 3) { do { forkit(); }; }
154 ? (print("parent\n"),sleep(1))
155 : (print("child\n"),exit) ;
162 ? (print("parent\n"),exit)
163 : (print("child\n"),sleep(1)) ;
206 foreach my $c (1,2,3) {
215 while (wait() != -1) { print "waited\n" }
231 ? print($Config{osname} eq $^O)
232 : print($Config{osname} eq $^O) ;
240 ? do { require Config; print($Config::Config{osname} eq $^O); }
241 : do { require Config; print($Config::Config{osname} eq $^O); }
248 my $cwd = cwd(); # Make sure we load Win32.pm while "../lib" still works.
255 print cwd() =~ /\Q$dir/i ? "ok 1 parent" : "not ok 1 parent";
264 print cwd() =~ /\Q$dir/i ? "ok 1 child" : "not ok 1 child";
275 if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
276 $getenv = qq[$^X -e "print \$ENV{TST}"];
279 $getenv = qq[$^X -e 'print \$ENV{TST}'];
284 print "parent before: " . `$getenv`;
286 print "parent after: " . `$getenv`;
289 print "child before: " . `$getenv`;
291 print "child after: " . `$getenv`;
303 print "parent got $?"
316 print "parent got $?"
332 parent died at - line 2.
333 child died at - line 5.
336 eval { die "parent died" };
340 eval { die "child died" };
344 parent died at - line 2.
345 child died at - line 6.
347 if (eval q{$pid = fork}) {
348 eval q{ die "parent died" };
352 eval q{ die "child died" };
356 parent died at (eval 2) line 1.
357 child died at (eval 2) line 1.
364 # XXX In emulated fork(), the child will not execute anything after
365 # the BEGIN block, due to difficulties in recreating the parse stacks
366 # and restarting yyparse() midstream in the child. This can potentially
367 # be overcome by treating what's after the BEGIN{} as a brand new parse.
372 sub pipe_to_fork ($$) {
375 pipe($child, $parent) or die;
377 die "fork() failed: $!" unless defined $pid;
378 close($pid ? $child : $parent);
382 if (pipe_to_fork('PARENT','CHILD')) {
384 print PARENT "pipe_to_fork\n";
389 while (<CHILD>) { print; }
394 sub pipe_from_fork ($$) {
397 pipe($parent, $child) or die;
399 die "fork() failed: $!" unless defined $pid;
400 close($pid ? $child : $parent);
404 if (pipe_from_fork('PARENT','CHILD')) {
406 while (<PARENT>) { print; }
411 print CHILD "pipe_from_fork\n";
421 print "forked first kid\n";
422 print "waitpid() returned ok\n" if waitpid($pid,0) == $pid;
425 print "first child\n";
429 print "forked second kid\n";
430 print "wait() returned ok\n" if wait() == $pid;
433 print "second child\n";
439 waitpid() returned ok
444 pipe(RDR,WTR) or die $!;
446 die "fork: $!" if !defined $pid;
449 print WTR "STRING_FROM_CHILD\n";
453 chomp(my $string_from_child = <RDR>);
455 print $string_from_child eq "STRING_FROM_CHILD", "\n";
460 # [perl #39145] Perl_dounwind() crashing with Win32's fork() emulation
461 sub { @_ = 3; fork ? die "1\n" : die "1\n" }->(2);