This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Test case for C<undef %File::Glob::>
[perl5.git] / t / op / fork.t
CommitLineData
8d063cd8
LW
1#!./perl
2
7766f137 3# tests for both real and emulated fork()
8d063cd8 4
774d564b 5BEGIN {
6 chdir 't' if -d 't';
20822f61 7 @INC = '../lib';
774d564b 8 require Config; import Config;
dfdd1393
GS
9 unless ($Config{'d_fork'}
10 or ($^O eq 'MSWin32' and $Config{useithreads}
5f1a76d0
NIS
11 and $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/
12# and !defined $Config{'useperlio'}
13 ))
dfdd1393 14 {
45c0de28 15 print "1..0 # Skip: no fork\n";
774d564b 16 exit 0;
17 }
7766f137 18 $ENV{PERL5LIB} = "../lib";
774d564b 19}
20
0994c4d0
JH
21if ($^O eq 'mpeix') {
22 print "1..0 # Skip: fork/status problems on MPE/iX\n";
23 exit 0;
24}
25
7766f137
GS
26$|=1;
27
28undef $/;
29@prgs = split "\n########\n", <DATA>;
30print "1..", scalar @prgs, "\n";
31
32$tmpfile = "forktmp000";
331 while -f ++$tmpfile;
6b5cb48c 34END { close TEST; unlink $tmpfile if $tmpfile; }
7766f137
GS
35
36$CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : 'cat');
8d063cd8 37
7766f137
GS
38for (@prgs){
39 my $switch;
40 if (s/^\s*(-\w.*)//){
41 $switch = $1;
42 }
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: $!";
50 my $results;
51 if ($^O eq 'MSWin32') {
52 $results = `.\\perl -I../lib $switch $tmpfile 2>&1`;
53 }
54 else {
55 $results = `./perl $switch $tmpfile 2>&1`;
56 }
57 $status = $?;
58 $results =~ s/\n+$//;
59 $results =~ s/at\s+forktmp\d+\s+line/at - line/g;
60 $results =~ s/of\s+forktmp\d+\s+aborted/of - aborted/g;
61# bison says 'parse error' instead of 'syntax error',
62# various yaccs may or may not capitalize 'syntax'.
63 $results =~ s/^(syntax|parse) error/syntax error/mig;
6b5cb48c
GS
64 $results =~ s/^\n*Process terminated by SIG\w+\n?//mg
65 if $^O eq 'os2';
7766f137
GS
66 my @results = sort split /\n/, $results;
67 if ( "@results" ne "@expected" ) {
68 print STDERR "PROG: $switch\n$prog\n";
69 print STDERR "EXPECTED:\n$expected\n";
70 print STDERR "GOT:\n$results\n";
71 print "not ";
72 }
73 print "ok ", ++$i, "\n";
74}
75
76__END__
77$| = 1;
8d063cd8 78if ($cid = fork) {
7766f137
GS
79 sleep 1;
80 if ($result = (kill 9, $cid)) {
81 print "ok 2\n";
82 }
83 else {
84 print "not ok 2 $result\n";
85 }
86 sleep 1 if $^O eq 'MSWin32'; # avoid WinNT race bug
8d063cd8
LW
87}
88else {
8d063cd8
LW
89 print "ok 1\n";
90 sleep 10;
91}
7766f137
GS
92EXPECT
93ok 1
94ok 2
95########
96$| = 1;
97sub forkit {
98 print "iteration $i start\n";
99 my $x = fork;
100 if (defined $x) {
101 if ($x) {
102 print "iteration $i parent\n";
103 }
104 else {
105 print "iteration $i child\n";
106 }
107 }
108 else {
109 print "pid $$ failed to fork\n";
110 }
111}
112while ($i++ < 3) { do { forkit(); }; }
113EXPECT
114iteration 1 start
115iteration 1 parent
116iteration 1 child
117iteration 2 start
118iteration 2 parent
119iteration 2 child
120iteration 2 start
121iteration 2 parent
122iteration 2 child
123iteration 3 start
124iteration 3 parent
125iteration 3 child
126iteration 3 start
127iteration 3 parent
128iteration 3 child
129iteration 3 start
130iteration 3 parent
131iteration 3 child
132iteration 3 start
133iteration 3 parent
134iteration 3 child
135########
136$| = 1;
137fork()
138 ? (print("parent\n"),sleep(1))
139 : (print("child\n"),exit) ;
140EXPECT
141parent
142child
143########
144$| = 1;
145fork()
146 ? (print("parent\n"),exit)
147 : (print("child\n"),sleep(1)) ;
148EXPECT
149parent
150child
151########
152$| = 1;
153@a = (1..3);
154for (@a) {
155 if (fork) {
156 print "parent $_\n";
157 $_ = "[$_]";
158 }
159 else {
160 print "child $_\n";
161 $_ = "-$_-";
162 }
163}
164print "@a\n";
165EXPECT
166parent 1
167child 1
168parent 2
169child 2
170parent 2
171child 2
172parent 3
173child 3
174parent 3
175child 3
176parent 3
177child 3
178parent 3
179child 3
180[1] [2] [3]
181-1- [2] [3]
182[1] -2- [3]
183[1] [2] -3-
184-1- -2- [3]
185-1- [2] -3-
186[1] -2- -3-
187-1- -2- -3-
188########
c3564e5c
GS
189$| = 1;
190foreach my $c (1,2,3) {
191 if (fork) {
192 print "parent $c\n";
193 }
194 else {
195 print "child $c\n";
196 exit;
197 }
198}
199while (wait() != -1) { print "waited\n" }
200EXPECT
201child 1
202child 2
203child 3
204parent 1
205parent 2
206parent 3
207waited
208waited
209waited
210########
7766f137
GS
211use Config;
212$| = 1;
213$\ = "\n";
214fork()
215 ? print($Config{osname} eq $^O)
216 : print($Config{osname} eq $^O) ;
217EXPECT
2181
2191
220########
221$| = 1;
222$\ = "\n";
223fork()
224 ? do { require Config; print($Config::Config{osname} eq $^O); }
225 : do { require Config; print($Config::Config{osname} eq $^O); }
226EXPECT
2271
2281
229########
230$| = 1;
231use Cwd;
232$\ = "\n";
233my $dir;
234if (fork) {
235 $dir = "f$$.tst";
236 mkdir $dir, 0755;
237 chdir $dir;
238 print cwd() =~ /\Q$dir/i ? "ok 1 parent" : "not ok 1 parent";
239 chdir "..";
240 rmdir $dir;
241}
242else {
243 sleep 2;
244 $dir = "f$$.tst";
245 mkdir $dir, 0755;
246 chdir $dir;
247 print cwd() =~ /\Q$dir/i ? "ok 1 child" : "not ok 1 child";
248 chdir "..";
249 rmdir $dir;
250}
251EXPECT
252ok 1 parent
253ok 1 child
254########
255$| = 1;
256$\ = "\n";
257my $getenv;
258if ($^O eq 'MSWin32') {
259 $getenv = qq[$^X -e "print \$ENV{TST}"];
260}
261else {
262 $getenv = qq[$^X -e 'print \$ENV{TST}'];
263}
35424068 264$ENV{TST} = 'foo';
7766f137
GS
265if (fork) {
266 sleep 1;
35424068
GS
267 print "parent before: " . `$getenv`;
268 $ENV{TST} = 'bar';
269 print "parent after: " . `$getenv`;
7766f137
GS
270}
271else {
35424068
GS
272 print "child before: " . `$getenv`;
273 $ENV{TST} = 'baz';
274 print "child after: " . `$getenv`;
7766f137
GS
275}
276EXPECT
35424068
GS
277child before: foo
278child after: baz
279parent before: foo
280parent after: bar
7766f137
GS
281########
282$| = 1;
283$\ = "\n";
284if ($pid = fork) {
285 waitpid($pid,0);
286 print "parent got $?"
287}
288else {
289 exit(42);
290}
291EXPECT
292parent got 10752
293########
294$| = 1;
295$\ = "\n";
296my $echo = 'echo';
297if ($pid = fork) {
298 waitpid($pid,0);
299 print "parent got $?"
300}
301else {
302 exec("$echo foo");
303}
304EXPECT
305foo
306parent got 0
307########
308if (fork) {
309 die "parent died";
310}
311else {
312 die "child died";
313}
314EXPECT
315parent died at - line 2.
316child died at - line 5.
317########
318if ($pid = fork) {
319 eval { die "parent died" };
320 print $@;
321}
322else {
323 eval { die "child died" };
324 print $@;
325}
326EXPECT
327parent died at - line 2.
328child died at - line 6.
329########
330if (eval q{$pid = fork}) {
331 eval q{ die "parent died" };
332 print $@;
333}
334else {
335 eval q{ die "child died" };
336 print $@;
337}
338EXPECT
339parent died at (eval 2) line 1.
340child died at (eval 2) line 1.
341########
342BEGIN {
343 $| = 1;
344 fork and exit;
345 print "inner\n";
346}
347# XXX In emulated fork(), the child will not execute anything after
348# the BEGIN block, due to difficulties in recreating the parse stacks
349# and restarting yyparse() midstream in the child. This can potentially
350# be overcome by treating what's after the BEGIN{} as a brand new parse.
351#print "outer\n"
352EXPECT
353inner
030866aa
GS
354########
355sub pipe_to_fork ($$) {
356 my $parent = shift;
357 my $child = shift;
358 pipe($child, $parent) or die;
359 my $pid = fork();
360 die "fork() failed: $!" unless defined $pid;
361 close($pid ? $child : $parent);
362 $pid;
363}
364
365if (pipe_to_fork('PARENT','CHILD')) {
366 # parent
367 print PARENT "pipe_to_fork\n";
368 close PARENT;
369}
370else {
371 # child
372 while (<CHILD>) { print; }
373 close CHILD;
374 exit;
375}
376
377sub pipe_from_fork ($$) {
378 my $parent = shift;
379 my $child = shift;
380 pipe($parent, $child) or die;
381 my $pid = fork();
382 die "fork() failed: $!" unless defined $pid;
383 close($pid ? $child : $parent);
384 $pid;
385}
386
387if (pipe_from_fork('PARENT','CHILD')) {
388 # parent
389 while (<PARENT>) { print; }
390 close PARENT;
391}
392else {
393 # child
394 print CHILD "pipe_from_fork\n";
395 close CHILD;
396 exit;
397}
398EXPECT
399pipe_from_fork
400pipe_to_fork
68a29c53 401########
10d51319 402$|=1;
68a29c53
GS
403if ($pid = fork()) {
404 print "forked first kid\n";
405 print "waitpid() returned ok\n" if waitpid($pid,0) == $pid;
406}
407else {
408 print "first child\n";
409 exit(0);
410}
411if ($pid = fork()) {
412 print "forked second kid\n";
413 print "wait() returned ok\n" if wait() == $pid;
414}
415else {
416 print "second child\n";
417 exit(0);
418}
419EXPECT
420forked first kid
421first child
422waitpid() returned ok
423forked second kid
424second child
425wait() returned ok