severe bugs in change#3786 fixed
[p5sagit/p5-mst-13.2.git] / t / op / fork.t
CommitLineData
8d063cd8 1#!./perl
2
7766f137 3# tests for both real and emulated fork()
8d063cd8 4
774d564b 5BEGIN {
6 chdir 't' if -d 't';
93430cb4 7 unshift @INC, '../lib';
774d564b 8 require Config; import Config;
7766f137 9 unless ($Config{'d_fork'} || $Config{ccflags} =~ /-DUSE_ITHREADS\b/) {
45c0de28 10 print "1..0 # Skip: no fork\n";
774d564b 11 exit 0;
12 }
7766f137 13 $ENV{PERL5LIB} = "../lib";
774d564b 14}
15
7766f137 16$|=1;
17
18undef $/;
19@prgs = split "\n########\n", <DATA>;
20print "1..", scalar @prgs, "\n";
21
22$tmpfile = "forktmp000";
231 while -f ++$tmpfile;
24END { unlink $tmpfile if $tmpfile; }
25
26$CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : 'cat');
8d063cd8 27
7766f137 28for (@prgs){
29 my $switch;
30 if (s/^\s*(-\w.*)//){
31 $switch = $1;
32 }
33 my($prog,$expected) = split(/\nEXPECT\n/, $_);
34 $expected =~ s/\n+$//;
35 # results can be in any order, so sort 'em
36 my @expected = sort split /\n/, $expected;
37 open TEST, ">$tmpfile" or die "Cannot open $tmpfile: $!";
38 print TEST $prog, "\n";
39 close TEST or die "Cannot close $tmpfile: $!";
40 my $results;
41 if ($^O eq 'MSWin32') {
42 $results = `.\\perl -I../lib $switch $tmpfile 2>&1`;
43 }
44 else {
45 $results = `./perl $switch $tmpfile 2>&1`;
46 }
47 $status = $?;
48 $results =~ s/\n+$//;
49 $results =~ s/at\s+forktmp\d+\s+line/at - line/g;
50 $results =~ s/of\s+forktmp\d+\s+aborted/of - aborted/g;
51# bison says 'parse error' instead of 'syntax error',
52# various yaccs may or may not capitalize 'syntax'.
53 $results =~ s/^(syntax|parse) error/syntax error/mig;
54 my @results = sort split /\n/, $results;
55 if ( "@results" ne "@expected" ) {
56 print STDERR "PROG: $switch\n$prog\n";
57 print STDERR "EXPECTED:\n$expected\n";
58 print STDERR "GOT:\n$results\n";
59 print "not ";
60 }
61 print "ok ", ++$i, "\n";
62}
63
64__END__
65$| = 1;
8d063cd8 66if ($cid = fork) {
7766f137 67 sleep 1;
68 if ($result = (kill 9, $cid)) {
69 print "ok 2\n";
70 }
71 else {
72 print "not ok 2 $result\n";
73 }
74 sleep 1 if $^O eq 'MSWin32'; # avoid WinNT race bug
8d063cd8 75}
76else {
8d063cd8 77 print "ok 1\n";
78 sleep 10;
79}
7766f137 80EXPECT
81ok 1
82ok 2
83########
84$| = 1;
85sub forkit {
86 print "iteration $i start\n";
87 my $x = fork;
88 if (defined $x) {
89 if ($x) {
90 print "iteration $i parent\n";
91 }
92 else {
93 print "iteration $i child\n";
94 }
95 }
96 else {
97 print "pid $$ failed to fork\n";
98 }
99}
100while ($i++ < 3) { do { forkit(); }; }
101EXPECT
102iteration 1 start
103iteration 1 parent
104iteration 1 child
105iteration 2 start
106iteration 2 parent
107iteration 2 child
108iteration 2 start
109iteration 2 parent
110iteration 2 child
111iteration 3 start
112iteration 3 parent
113iteration 3 child
114iteration 3 start
115iteration 3 parent
116iteration 3 child
117iteration 3 start
118iteration 3 parent
119iteration 3 child
120iteration 3 start
121iteration 3 parent
122iteration 3 child
123########
124$| = 1;
125fork()
126 ? (print("parent\n"),sleep(1))
127 : (print("child\n"),exit) ;
128EXPECT
129parent
130child
131########
132$| = 1;
133fork()
134 ? (print("parent\n"),exit)
135 : (print("child\n"),sleep(1)) ;
136EXPECT
137parent
138child
139########
140$| = 1;
141@a = (1..3);
142for (@a) {
143 if (fork) {
144 print "parent $_\n";
145 $_ = "[$_]";
146 }
147 else {
148 print "child $_\n";
149 $_ = "-$_-";
150 }
151}
152print "@a\n";
153EXPECT
154parent 1
155child 1
156parent 2
157child 2
158parent 2
159child 2
160parent 3
161child 3
162parent 3
163child 3
164parent 3
165child 3
166parent 3
167child 3
168[1] [2] [3]
169-1- [2] [3]
170[1] -2- [3]
171[1] [2] -3-
172-1- -2- [3]
173-1- [2] -3-
174[1] -2- -3-
175-1- -2- -3-
176########
177use Config;
178$| = 1;
179$\ = "\n";
180fork()
181 ? print($Config{osname} eq $^O)
182 : print($Config{osname} eq $^O) ;
183EXPECT
1841
1851
186########
187$| = 1;
188$\ = "\n";
189fork()
190 ? do { require Config; print($Config::Config{osname} eq $^O); }
191 : do { require Config; print($Config::Config{osname} eq $^O); }
192EXPECT
1931
1941
195########
196$| = 1;
197use Cwd;
198$\ = "\n";
199my $dir;
200if (fork) {
201 $dir = "f$$.tst";
202 mkdir $dir, 0755;
203 chdir $dir;
204 print cwd() =~ /\Q$dir/i ? "ok 1 parent" : "not ok 1 parent";
205 chdir "..";
206 rmdir $dir;
207}
208else {
209 sleep 2;
210 $dir = "f$$.tst";
211 mkdir $dir, 0755;
212 chdir $dir;
213 print cwd() =~ /\Q$dir/i ? "ok 1 child" : "not ok 1 child";
214 chdir "..";
215 rmdir $dir;
216}
217EXPECT
218ok 1 parent
219ok 1 child
220########
221$| = 1;
222$\ = "\n";
223my $getenv;
224if ($^O eq 'MSWin32') {
225 $getenv = qq[$^X -e "print \$ENV{TST}"];
226}
227else {
228 $getenv = qq[$^X -e 'print \$ENV{TST}'];
229}
230if (fork) {
231 sleep 1;
232 $ENV{TST} = 'foo';
233 print "parent: " . `$getenv`;
234}
235else {
236 $ENV{TST} = 'bar';
237 print "child: " . `$getenv`;
238 sleep 1;
239}
240EXPECT
241parent: foo
242child: bar
243########
244$| = 1;
245$\ = "\n";
246if ($pid = fork) {
247 waitpid($pid,0);
248 print "parent got $?"
249}
250else {
251 exit(42);
252}
253EXPECT
254parent got 10752
255########
256$| = 1;
257$\ = "\n";
258my $echo = 'echo';
259if ($pid = fork) {
260 waitpid($pid,0);
261 print "parent got $?"
262}
263else {
264 exec("$echo foo");
265}
266EXPECT
267foo
268parent got 0
269########
270if (fork) {
271 die "parent died";
272}
273else {
274 die "child died";
275}
276EXPECT
277parent died at - line 2.
278child died at - line 5.
279########
280if ($pid = fork) {
281 eval { die "parent died" };
282 print $@;
283}
284else {
285 eval { die "child died" };
286 print $@;
287}
288EXPECT
289parent died at - line 2.
290child died at - line 6.
291########
292if (eval q{$pid = fork}) {
293 eval q{ die "parent died" };
294 print $@;
295}
296else {
297 eval q{ die "child died" };
298 print $@;
299}
300EXPECT
301parent died at (eval 2) line 1.
302child died at (eval 2) line 1.
303########
304BEGIN {
305 $| = 1;
306 fork and exit;
307 print "inner\n";
308}
309# XXX In emulated fork(), the child will not execute anything after
310# the BEGIN block, due to difficulties in recreating the parse stacks
311# and restarting yyparse() midstream in the child. This can potentially
312# be overcome by treating what's after the BEGIN{} as a brand new parse.
313#print "outer\n"
314EXPECT
315inner