3 # tests for both real and emulated fork()
8 require Config; import Config;
9 unless ($Config{'d_fork'}
10 or (($^O eq 'MSWin32' || $^O eq 'NetWare') and $Config{useithreads}
11 and $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/
12 # and !defined $Config{'useperlio'}
15 print "1..0 # Skip: no fork\n";
18 $ENV{PERL5LIB} = "../lib";
22 print "1..0 # Skip: fork/status problems on MPE/iX\n";
29 @prgs = split "\n########\n", <DATA>;
30 print "1..", scalar @prgs, "\n";
32 $tmpfile = "forktmp000";
33 1 while -f ++$tmpfile;
34 END { close TEST; unlink $tmpfile if $tmpfile; }
36 $CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : (($^O eq 'NetWare') ? 'perl -e "print <>"' : 'cat'));
43 my($prog,$expected) = split(/\nEXPECT\n/, $_);
44 $expected =~ s/\n+$//;
45 # results can be in any order, so sort 'em
46 my @expected = sort split /\n/, $expected;
47 open TEST, ">$tmpfile" or die "Cannot open $tmpfile: $!";
48 print TEST $prog, "\n";
49 close TEST or die "Cannot close $tmpfile: $!";
51 if ($^O eq 'MSWin32') {
52 $results = `.\\perl -I../lib $switch $tmpfile 2>&1`;
54 elsif ($^O eq 'NetWare') {
55 $results = `perl -I../lib $switch $tmpfile 2>&1`;
58 $results = `./perl $switch $tmpfile 2>&1`;
62 $results =~ s/at\s+forktmp\d+\s+line/at - line/g;
63 $results =~ s/of\s+forktmp\d+\s+aborted/of - aborted/g;
64 # bison says 'parse error' instead of 'syntax error',
65 # various yaccs may or may not capitalize 'syntax'.
66 $results =~ s/^(syntax|parse) error/syntax error/mig;
67 $results =~ s/^\n*Process terminated by SIG\w+\n?//mg
69 my @results = sort split /\n/, $results;
70 if ( "@results" ne "@expected" ) {
71 print STDERR "PROG: $switch\n$prog\n";
72 print STDERR "EXPECTED:\n$expected\n";
73 print STDERR "GOT:\n$results\n";
76 print "ok ", ++$i, "\n";
83 if ($result = (kill 9, $cid)) {
87 print "not ok 2 $result\n";
89 sleep 1 if $^O eq 'MSWin32'; # avoid WinNT race bug
101 print "iteration $i start\n";
105 print "iteration $i parent\n";
108 print "iteration $i child\n";
112 print "pid $$ failed to fork\n";
115 while ($i++ < 3) { do { forkit(); }; }
141 ? (print("parent\n"),sleep(1))
142 : (print("child\n"),exit) ;
149 ? (print("parent\n"),exit)
150 : (print("child\n"),sleep(1)) ;
193 foreach my $c (1,2,3) {
202 while (wait() != -1) { print "waited\n" }
218 ? print($Config{osname} eq $^O)
219 : print($Config{osname} eq $^O) ;
227 ? do { require Config; print($Config::Config{osname} eq $^O); }
228 : do { require Config; print($Config::Config{osname} eq $^O); }
241 print cwd() =~ /\Q$dir/i ? "ok 1 parent" : "not ok 1 parent";
250 print cwd() =~ /\Q$dir/i ? "ok 1 child" : "not ok 1 child";
261 if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
262 $getenv = qq[$^X -e "print \$ENV{TST}"];
265 $getenv = qq[$^X -e 'print \$ENV{TST}'];
270 print "parent before: " . `$getenv`;
272 print "parent after: " . `$getenv`;
275 print "child before: " . `$getenv`;
277 print "child after: " . `$getenv`;
289 print "parent got $?"
302 print "parent got $?"
318 parent died at - line 2.
319 child died at - line 5.
322 eval { die "parent died" };
326 eval { die "child died" };
330 parent died at - line 2.
331 child died at - line 6.
333 if (eval q{$pid = fork}) {
334 eval q{ die "parent died" };
338 eval q{ die "child died" };
342 parent died at (eval 2) line 1.
343 child died at (eval 2) line 1.
350 # XXX In emulated fork(), the child will not execute anything after
351 # the BEGIN block, due to difficulties in recreating the parse stacks
352 # and restarting yyparse() midstream in the child. This can potentially
353 # be overcome by treating what's after the BEGIN{} as a brand new parse.
358 sub pipe_to_fork ($$) {
361 pipe($child, $parent) or die;
363 die "fork() failed: $!" unless defined $pid;
364 close($pid ? $child : $parent);
368 if (pipe_to_fork('PARENT','CHILD')) {
370 print PARENT "pipe_to_fork\n";
375 while (<CHILD>) { print; }
380 sub pipe_from_fork ($$) {
383 pipe($parent, $child) or die;
385 die "fork() failed: $!" unless defined $pid;
386 close($pid ? $child : $parent);
390 if (pipe_from_fork('PARENT','CHILD')) {
392 while (<PARENT>) { print; }
397 print CHILD "pipe_from_fork\n";
407 print "forked first kid\n";
408 print "waitpid() returned ok\n" if waitpid($pid,0) == $pid;
411 print "first child\n";
415 print "forked second kid\n";
416 print "wait() returned ok\n" if wait() == $pid;
419 print "second child\n";
425 waitpid() returned ok