add $VERSION
[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;
dedd9aeb 9 unless ($Config{'d_fork'} || ($^O eq 'MSWin32' && $Config{'useithreads'})) {
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}
35424068 230$ENV{TST} = 'foo';
7766f137 231if (fork) {
232 sleep 1;
35424068 233 print "parent before: " . `$getenv`;
234 $ENV{TST} = 'bar';
235 print "parent after: " . `$getenv`;
7766f137 236}
237else {
35424068 238 print "child before: " . `$getenv`;
239 $ENV{TST} = 'baz';
240 print "child after: " . `$getenv`;
7766f137 241}
242EXPECT
35424068 243child before: foo
244child after: baz
245parent before: foo
246parent after: bar
7766f137 247########
248$| = 1;
249$\ = "\n";
250if ($pid = fork) {
251 waitpid($pid,0);
252 print "parent got $?"
253}
254else {
255 exit(42);
256}
257EXPECT
258parent got 10752
259########
260$| = 1;
261$\ = "\n";
262my $echo = 'echo';
263if ($pid = fork) {
264 waitpid($pid,0);
265 print "parent got $?"
266}
267else {
268 exec("$echo foo");
269}
270EXPECT
271foo
272parent got 0
273########
274if (fork) {
275 die "parent died";
276}
277else {
278 die "child died";
279}
280EXPECT
281parent died at - line 2.
282child died at - line 5.
283########
284if ($pid = fork) {
285 eval { die "parent died" };
286 print $@;
287}
288else {
289 eval { die "child died" };
290 print $@;
291}
292EXPECT
293parent died at - line 2.
294child died at - line 6.
295########
296if (eval q{$pid = fork}) {
297 eval q{ die "parent died" };
298 print $@;
299}
300else {
301 eval q{ die "child died" };
302 print $@;
303}
304EXPECT
305parent died at (eval 2) line 1.
306child died at (eval 2) line 1.
307########
308BEGIN {
309 $| = 1;
310 fork and exit;
311 print "inner\n";
312}
313# XXX In emulated fork(), the child will not execute anything after
314# the BEGIN block, due to difficulties in recreating the parse stacks
315# and restarting yyparse() midstream in the child. This can potentially
316# be overcome by treating what's after the BEGIN{} as a brand new parse.
317#print "outer\n"
318EXPECT
319inner