This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update Maintainers.PL for divergence from cpan
[perl5.git] / t / op / fork.t
1 #!./perl
2
3 # tests for both real and emulated fork()
4
5 BEGIN {
6     chdir 't' if -d 't';
7     @INC = '../lib';
8     require './test.pl';
9     require Config;
10     skip_all('no fork')
11         unless ($Config::Config{d_fork} or $Config::Config{d_pseudofork});
12 }
13
14 $|=1;
15
16 run_multiple_progs('', \*DATA);
17
18 my $shell = $ENV{SHELL} || '';
19 SKIP: {
20     skip "This test can only be run under bash or zsh"
21         unless $shell =~ m{/(?:ba|z)sh$};
22     my $probe = qx{
23         $shell -c 'ulimit -u 1 2>&1 && echo good'
24     };
25     chomp $probe;
26     skip "Can't set ulimit -u on this system: $probe"
27         unless $probe eq 'good';
28
29     my $out = qx{
30         $shell -c 'ulimit -u 1; exec $^X -e "
31             print((() = fork) == 1 ? q[ok] : q[not ok])
32         "'
33     };
34     # perl #117141
35     skip "fork() didn't fail, maybe you're running as root", 1
36       if $out eq "okok";
37     is($out, "ok", "bash/zsh-only test for 'fork' returning undef on failure");
38 }
39
40 done_testing();
41
42 __END__
43 $| = 1;
44 if ($cid = fork) {
45     sleep 1;
46     if ($result = (kill 9, $cid)) {
47         print "ok 2\n";
48     }
49     else {
50         print "not ok 2 $result\n";
51     }
52     sleep 1 if $^O eq 'MSWin32';        # avoid WinNT race bug
53 }
54 else {
55     print "ok 1\n";
56     sleep 10;
57 }
58 EXPECT
59 OPTION random
60 ok 1
61 ok 2
62 ########
63 $| = 1;
64 if ($cid = fork) {
65     sleep 1;
66     print "not " unless kill 'INT', $cid;
67     print "ok 2\n";
68 }
69 else {
70     # XXX On Windows the default signal handler kills the
71     # XXX whole process, not just the thread (pseudo-process)
72     $SIG{INT} = sub { exit };
73     print "ok 1\n";
74     sleep 5;
75     die;
76 }
77 EXPECT
78 OPTION random
79 ok 1
80 ok 2
81 ########
82 $| = 1;
83 sub forkit {
84     print "iteration $i start\n";
85     my $x = fork;
86     if (defined $x) {
87         if ($x) {
88             print "iteration $i parent\n";
89         }
90         else {
91             print "iteration $i child\n";
92         }
93     }
94     else {
95         print "pid $$ failed to fork\n";
96     }
97 }
98 while ($i++ < 3) { do { forkit(); }; }
99 EXPECT
100 OPTION random
101 iteration 1 start
102 iteration 1 parent
103 iteration 1 child
104 iteration 2 start
105 iteration 2 parent
106 iteration 2 child
107 iteration 2 start
108 iteration 2 parent
109 iteration 2 child
110 iteration 3 start
111 iteration 3 parent
112 iteration 3 child
113 iteration 3 start
114 iteration 3 parent
115 iteration 3 child
116 iteration 3 start
117 iteration 3 parent
118 iteration 3 child
119 iteration 3 start
120 iteration 3 parent
121 iteration 3 child
122 ########
123 $| = 1;
124 fork()
125  ? (print("parent\n"),sleep(1))
126  : (print("child\n"),exit) ;
127 EXPECT
128 OPTION random
129 parent
130 child
131 ########
132 $| = 1;
133 fork()
134  ? (print("parent\n"),exit)
135  : (print("child\n"),sleep(1)) ;
136 EXPECT
137 OPTION random
138 parent
139 child
140 ########
141 $| = 1;
142 @a = (1..3);
143 for (@a) {
144     if (fork) {
145         print "parent $_\n";
146         $_ = "[$_]";
147     }
148     else {
149         print "child $_\n";
150         $_ = "-$_-";
151     }
152 }
153 print "@a\n";
154 EXPECT
155 OPTION random
156 parent 1
157 child 1
158 parent 2
159 child 2
160 parent 2
161 child 2
162 parent 3
163 child 3
164 parent 3
165 child 3
166 parent 3
167 child 3
168 parent 3
169 child 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 [1] -2- -3-
177 -1- -2- -3-
178 ########
179 $| = 1;
180 foreach my $c (1,2,3) {
181     if (fork) {
182         print "parent $c\n";
183     }
184     else {
185         print "child $c\n";
186         exit;
187     }
188 }
189 while (wait() != -1) { print "waited\n" }
190 EXPECT
191 OPTION random
192 child 1
193 child 2
194 child 3
195 parent 1
196 parent 2
197 parent 3
198 waited
199 waited
200 waited
201 ########
202 use Config;
203 $| = 1;
204 $\ = "\n";
205 fork()
206  ? print($Config{osname} eq $^O)
207  : print($Config{osname} eq $^O) ;
208 EXPECT
209 OPTION random
210 1
211 1
212 ########
213 $| = 1;
214 $\ = "\n";
215 fork()
216  ? do { require Config; print($Config::Config{osname} eq $^O); }
217  : do { require Config; print($Config::Config{osname} eq $^O); }
218 EXPECT
219 OPTION random
220 1
221 1
222 ########
223 $| = 1;
224 use Cwd;
225 my $cwd = cwd(); # Make sure we load Win32.pm while "../lib" still works.
226 $\ = "\n";
227 my $dir;
228 if (fork) {
229     $dir = "f$$.tst";
230     mkdir $dir, 0755;
231     chdir $dir;
232     print cwd() =~ /\Q$dir/i ? "ok 1 parent" : "not ok 1 parent";
233     chdir "..";
234     rmdir $dir;
235 }
236 else {
237     sleep 2;
238     $dir = "f$$.tst";
239     mkdir $dir, 0755;
240     chdir $dir;
241     print cwd() =~ /\Q$dir/i ? "ok 1 child" : "not ok 1 child";
242     chdir "..";
243     rmdir $dir;
244 }
245 EXPECT
246 OPTION random
247 ok 1 parent
248 ok 1 child
249 ########
250 $| = 1;
251 $\ = "\n";
252 my $getenv;
253 if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
254     $getenv = qq[$^X -e "print \$ENV{TST}"];
255 }
256 else {
257     $getenv = qq[$^X -e 'print \$ENV{TST}'];
258 }
259 $ENV{TST} = 'foo';
260 if (fork) {
261     sleep 1;
262     print "parent before: " . `$getenv`;
263     $ENV{TST} = 'bar';
264     print "parent after: " . `$getenv`;
265 }
266 else {
267     print "child before: " . `$getenv`;
268     $ENV{TST} = 'baz';
269     print "child after: " . `$getenv`;
270 }
271 EXPECT
272 OPTION random
273 child before: foo
274 child after: baz
275 parent before: foo
276 parent after: bar
277 ########
278 $| = 1;
279 $\ = "\n";
280 if ($pid = fork) {
281     waitpid($pid,0);
282     print "parent got $?"
283 }
284 else {
285     exit(42);
286 }
287 EXPECT
288 OPTION random
289 parent got 10752
290 ########
291 $| = 1;
292 $\ = "\n";
293 my $echo = 'echo';
294 if ($pid = fork) {
295     waitpid($pid,0);
296     print "parent got $?"
297 }
298 else {
299     exec("$echo foo");
300 }
301 EXPECT
302 OPTION random
303 foo
304 parent got 0
305 ########
306 if (fork) {
307     die "parent died";
308 }
309 else {
310     die "child died";
311 }
312 EXPECT
313 OPTION random
314 parent died at - line 2.
315 child died at - line 5.
316 ########
317 if ($pid = fork) {
318     eval { die "parent died" };
319     print $@;
320 }
321 else {
322     eval { die "child died" };
323     print $@;
324 }
325 EXPECT
326 OPTION random
327 parent died at - line 2.
328 child died at - line 6.
329 ########
330 if (eval q{$pid = fork}) {
331     eval q{ die "parent died" };
332     print $@;
333 }
334 else {
335     eval q{ die "child died" };
336     print $@;
337 }
338 EXPECT
339 OPTION random
340 parent died at (eval 2) line 1.
341 child died at (eval 2) line 1.
342 ########
343 BEGIN {
344     $| = 1;
345     fork and exit;
346     print "inner\n";
347 }
348 # XXX In emulated fork(), the child will not execute anything after
349 # the BEGIN block, due to difficulties in recreating the parse stacks
350 # and restarting yyparse() midstream in the child.  This can potentially
351 # be overcome by treating what's after the BEGIN{} as a brand new parse.
352 #print "outer\n"
353 EXPECT
354 OPTION random
355 inner
356 ########
357 sub pipe_to_fork ($$) {
358     my $parent = shift;
359     my $child = shift;
360     pipe($child, $parent) or die;
361     my $pid = fork();
362     die "fork() failed: $!" unless defined $pid;
363     close($pid ? $child : $parent);
364     $pid;
365 }
366
367 if (pipe_to_fork('PARENT','CHILD')) {
368     # parent
369     print PARENT "pipe_to_fork\n";
370     close PARENT;
371 }
372 else {
373     # child
374     while (<CHILD>) { print; }
375     close CHILD;
376     exit;
377 }
378
379 sub pipe_from_fork ($$) {
380     my $parent = shift;
381     my $child = shift;
382     pipe($parent, $child) or die;
383     my $pid = fork();
384     die "fork() failed: $!" unless defined $pid;
385     close($pid ? $child : $parent);
386     $pid;
387 }
388
389 if (pipe_from_fork('PARENT','CHILD')) {
390     # parent
391     while (<PARENT>) { print; }
392     close PARENT;
393 }
394 else {
395     # child
396     print CHILD "pipe_from_fork\n";
397     close CHILD;
398     exit;
399 }
400 EXPECT
401 OPTION random
402 pipe_from_fork
403 pipe_to_fork
404 ########
405 $|=1;
406 if ($pid = fork()) {
407     print "forked first kid\n";
408     print "waitpid() returned ok\n" if waitpid($pid,0) == $pid;
409 }
410 else {
411     print "first child\n";
412     exit(0);
413 }
414 if ($pid = fork()) {
415     print "forked second kid\n";
416     print "wait() returned ok\n" if wait() == $pid;
417 }
418 else {
419     print "second child\n";
420     exit(0);
421 }
422 EXPECT
423 OPTION random
424 forked first kid
425 first child
426 waitpid() returned ok
427 forked second kid
428 second child
429 wait() returned ok
430 ########
431 pipe(RDR,WTR) or die $!;
432 my $pid = fork;
433 die "fork: $!" if !defined $pid;
434 if ($pid == 0) {
435     close RDR;
436     print WTR "STRING_FROM_CHILD\n";
437     close WTR;
438 } else {
439     close WTR;
440     chomp(my $string_from_child  = <RDR>);
441     close RDR;
442     print $string_from_child eq "STRING_FROM_CHILD", "\n";
443 }
444 EXPECT
445 OPTION random
446 1
447 ########
448 # [perl #39145] Perl_dounwind() crashing with Win32's fork() emulation
449 sub { @_ = 3; fork ? die "1\n" : die "1\n" }->(2);
450 EXPECT
451 OPTION random
452 1
453 1
454 ########
455 # [perl #72604] @DB::args stops working across Win32 fork
456 $|=1;
457 sub f {
458     if ($pid = fork()) {
459         print "waitpid() returned ok\n" if waitpid($pid,0) == $pid;
460     }
461     else {
462         package DB;
463         my @c = caller(0);
464         print "child: called as [$c[3](", join(',',@DB::args), ")]\n";
465         exit(0);
466     }
467 }
468 f("foo", "bar");
469 EXPECT
470 OPTION random
471 child: called as [main::f(foo,bar)]
472 waitpid() returned ok
473 ########
474 # Windows 2000: https://rt.cpan.org/Ticket/Display.html?id=66016#txn-908976
475 system $^X,  "-e", "if (\$pid=fork){sleep 1;kill(9, \$pid)} else {sleep 5}";
476 print $?>>8, "\n";
477 EXPECT
478 0
479 ########
480 # Windows 7: https://rt.cpan.org/Ticket/Display.html?id=66016#txn-908976
481 system $^X,  "-e", "if (\$pid=fork){kill(9, \$pid)} else {sleep 5}";
482 print $?>>8, "\n";
483 EXPECT
484 0
485 ########
486 # Windows fork() emulation: can we still waitpid() after signalling SIGTERM?
487 $|=1;
488 if (my $pid = fork) {
489     sleep 1;
490     print "1\n";
491     kill 'TERM', $pid;
492     waitpid($pid, 0);
493     print "4\n";
494 }
495 else {
496     $SIG{TERM} = sub { print "2\n" };
497     sleep 3;
498     print "3\n";
499 }
500 EXPECT
501 1
502 2
503 3
504 4