This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
bisect-runner.pl can now build all revisions on sparc64 Linux.
[perl5.git] / Porting / bisect-runner.pl
1 #!/usr/bin/perl -w
2 use strict;
3
4 use Getopt::Long qw(:config bundling no_auto_abbrev);
5 use Pod::Usage;
6 use Config;
7
8 my @targets
9     = qw(config.sh config.h miniperl lib/Config.pm Fcntl perl test_prep);
10
11 my $cpus;
12 if (open my $fh, '<', '/proc/cpuinfo') {
13     while (<$fh>) {
14         ++$cpus if /^processor\s+:\s+\d+$/;
15     }
16 } elsif (-x '/sbin/sysctl') {
17     $cpus = 1 + $1 if `/sbin/sysctl hw.ncpu` =~ /^hw\.ncpu: (\d+)$/;
18 } elsif (-x '/usr/bin/getconf') {
19     $cpus = 1 + $1 if `/usr/bin/getconf _NPROCESSORS_ONLN` =~ /^(\d+)$/;
20 }
21
22 my %options =
23     (
24      jobs => defined $cpus ? $cpus + 1 : 2,
25      'expect-pass' => 1,
26      clean => 1, # mostly for debugging this
27     );
28
29 my $linux64 = `uname -sm` eq "Linux x86_64\n" ? '64' : '';
30
31 my @paths;
32
33 if ($^O eq 'linux') {
34     # This is the search logic for a multi-arch library layout
35     # added to linux.sh in commits 40f026236b9959b7 and dcffd848632af2c7.
36     my $gcc = -x '/usr/bin/gcc' ? '/usr/bin/gcc' : 'gcc';
37
38     foreach (`$gcc -print-search-dirs`) {
39         next unless /^libraries: =(.*)/;
40         foreach (split ':', $1) {
41             next if m/gcc/;
42             next unless -d $_;
43             s!/$!!;
44             push @paths, $_;
45         }
46     }
47 }
48
49 push @paths, map {$_ . $linux64} qw(/usr/local/lib /lib /usr/lib);
50
51 my %defines =
52     (
53      usedevel => '',
54      optimize => '-g',
55      cc => 'ccache cc',
56      ld => 'cc',
57      ($linux64 ? (libpth => \@paths) : ()),
58     );
59
60 unless(GetOptions(\%options,
61                   'target=s', 'jobs|j=i', 'expect-pass=i',
62                   'expect-fail' => sub { $options{'expect-pass'} = 0; },
63                   'clean!', 'one-liner|e=s', 'match=s', 'force-manifest',
64                   'test-build', 'check-args', 'A=s@', 'usage|help|?',
65                   'D=s@' => sub {
66                       my (undef, $val) = @_;
67                       if ($val =~ /\A([^=]+)=(.*)/s) {
68                           $defines{$1} = length $2 ? $2 : "\0";
69                       } else {
70                           $defines{$val} = '';
71                       }
72                   },
73                   'U=s@' => sub {
74                       $defines{$_[1]} = undef;
75                   },
76                  )) {
77     pod2usage(exitval => 255, verbose => 1);
78 }
79
80 my ($target, $j, $match) = @options{qw(target jobs match)};
81
82 pod2usage(exitval => 255, verbose => 1) if $options{usage};
83 pod2usage(exitval => 255, verbose => 1)
84     unless @ARGV || $match || $options{'test-build'} || defined $options{'one-liner'};
85
86 exit 0 if $options{'check-args'};
87
88 =head1 NAME
89
90 bisect.pl - use git bisect to pinpoint changes
91
92 =head1 SYNOPSIS
93
94     # When did this become an error?
95     .../Porting/bisect.pl -e 'my $a := 2;'
96     # When did this stop being an error?
97     .../Porting/bisect.pl --expect-fail -e '1 // 2'
98     # When did this stop matching?
99     .../Porting/bisect.pl --match '\b(?:PL_)hash_seed_set\b'
100     # When did this start matching?
101     .../Porting/bisect.pl --expect-fail --match '\buseithreads\b'
102     # When did this test program stop working?
103     .../Porting/bisect.pl -- ./perl -Ilib ../test_prog.pl
104     # When did this first become valid syntax?
105     .../Porting/bisect.pl --target=miniperl --end=v5.10.0 \
106          --expect-fail -e 'my $a := 2;'
107     # What was the last revision to build with these options?
108     .../Porting/bisect.pl --test-build -Dd_dosuid
109
110 =head1 DESCRIPTION
111
112 Together F<bisect.pl> and F<bisect-runner.pl> attempt to automate the use
113 of C<git bisect> as much as possible. With one command (and no other files)
114 it's easy to find out
115
116 =over 4
117
118 =item *
119
120 Which commit caused this example code to break?
121
122 =item *
123
124 Which commit caused this example code to start working?
125
126 =item *
127
128 Which commit added the first to match this regex?
129
130 =item *
131
132 Which commit removed the last to match this regex?
133
134 =back
135
136 usually without needing to know which versions of perl to use as start and
137 end revisions.
138
139 By default F<bisect.pl> will process all options, then use the rest of the
140 command line as arguments to list C<system> to run a test case. By default,
141 the test case should pass (exit with 0) on earlier perls, and fail (exit
142 non-zero) on I<blead>. F<bisect.pl> will use F<bisect-runner.pl> to find the
143 earliest stable perl version on which the test case passes, check that it
144 fails on blead, and then use F<bisect-runner.pl> with C<git bisect run> to
145 find the commit which caused the failure.
146
147 Because the test case is the complete argument to C<system>, it is easy to
148 run something other than the F<perl> built, if necessary. If you need to run
149 the perl built, you'll probably need to invoke it as C<./perl -Ilib ...>
150
151 You need a clean checkout to run a bisect, and you can't use the checkout
152 which contains F<Porting/bisect.pl> (because C<git bisect>) will check out
153 a revision before F<Porting/bisect-runner.pl> was added, which
154 C<git bisect run> needs). If your working checkout is called F<perl>, the
155 simplest solution is to make a local clone, and run from that. I<i.e.>:
156
157     cd ..
158     git clone perl perl2
159     cd perl2
160     ../perl/Porting/bisect.pl ...
161
162 By default, F<bisect-runner.pl> will automatically disable the build of
163 L<DB_File> for commits earlier than ccb44e3bf3be2c30, as it's not practical
164 to patch DB_File 1.70 and earlier to build with current Berkeley DB headers.
165 (ccb44e3bf3be2c30 was in September 1999, between 5.005_62 and 5.005_63.)
166 If your F<db.h> is old enough you can override this with C<-Unoextensions>.
167
168 =head1 OPTIONS
169
170 =over 4
171
172 =item *
173
174 --start I<commit-ish>
175
176 Earliest revision to test, as a I<commit-ish> (a tag, commit or anything
177 else C<git> understands as a revision). If not specified, F<bisect.pl> will
178 search stable perl releases from 5.002 to 5.14.0 until it finds one where
179 the test case passes.
180
181 =item *
182
183 --end I<commit-ish>
184
185 Most recent revision to test, as a I<commit-ish>. If not specified, defaults
186 to I<blead>.
187
188 =item *
189
190 --target I<target>
191
192 F<Makefile> target (or equivalent) needed, to run the test case. If specified,
193 this should be one of
194
195 =over 4
196
197 =item *
198
199 I<config.sh>
200
201 Just run F<./Configure>
202
203 =item *
204
205 I<config.h>
206
207 Run the various F<*.SH> files to generate F<Makefile>, F<config.h>, I<etc>.
208
209 =item *
210
211 I<miniperl>
212
213 Build F<miniperl>.
214
215 =item *
216
217 I<lib/Config.pm>
218
219 Use F<miniperl> to build F<lib/Config.pm>
220
221 =item *
222
223 I<Fcntl>
224
225 Build F<lib/auto/Fcntl/Fnctl.so> (strictly, C<.$Config{so}>). As L<Fcntl>
226 is simple XS module present since 5.000, this provides a fast test of
227 whether XS modules can be built. Note, XS modules are built by F<miniperl>,
228 hence this target will not build F<perl>.
229
230 =item *
231
232 I<perl>
233
234 Build F<perl>. This also builds pure-Perl modules in F<cpan>, F<dist> and
235 F<ext>. XS modules (such as L<Fcntl>) are not built.
236
237 =item *
238
239 I<test_prep>
240
241 Build everything needed to run the tests. This is the default if we're
242 running test code, but is time consuming, as it means building all
243 XS modules. For older F<Makefile>s, the previous name of C<test-prep>
244 is automatically substituted. For very old F<Makefile>s, C<make test> is
245 run, as there is no target provided to just get things ready, and for 5.004
246 and earlier the tests run very quickly.
247
248 =back
249
250 =item *
251
252 --one-liner 'code to run'
253
254 =item *
255
256 -e 'code to run'
257
258 Example code to run, just like you'd use with C<perl -e>.
259
260 This prepends C<./perl -Ilib -e 'code to run'> to the test case given,
261 or F<./miniperl> if I<target> is C<miniperl>.
262
263 (Usually you'll use C<-e> instead of providing a test case in the
264 non-option arguments to F<bisect.pl>)
265
266 C<-E> intentionally isn't supported, as it's an error in 5.8.0 and earlier,
267 which interferes with detecting errors in the example code itself.
268
269 =item *
270
271 --expect-fail
272
273 The test case should fail for the I<start> revision, and pass for the I<end>
274 revision. The bisect run will find the first commit where it passes.
275
276 =item *
277
278 -Dnoextensions=Encode
279
280 =item *
281
282 -Uusedevel
283
284 =item *
285
286 -Accflags=-DNO_MATHOMS
287
288 Arguments to pass to F<Configure>. Repeated C<-A> arguments are passed
289 through as is. C<-D> and C<-U> are processed in order, and override
290 previous settings for the same parameter. F<bisect-runner.pl> emulates
291 C<-Dnoextensions> when F<Configure> itself does not provide it, as it's
292 often very useful to be able to disable some XS extensions.
293
294 =item *
295
296 --jobs I<jobs>
297
298 =item *
299
300 -j I<jobs>
301
302 Number of C<make> jobs to run in parallel. If F</proc/cpuinfo> exists and
303 can be parsed, or F</sbin/sysctl> exists and reports C<hw.ncpu>, or
304 F</usr/bin/getconf> exists and reports C<_NPROCESSORS_ONLN> defaults to 1 +
305 I<number of CPUs>. Otherwise defaults to 2.
306
307 =item *
308
309 --match pattern
310
311 Instead of running a test program to determine I<pass> or I<fail>, pass
312 if the given regex matches, and hence search for the commit that removes
313 the last matching file.
314
315 If no I<target> is specified, the match is against all files in the
316 repository (which is fast). If a I<target> is specified, that target is
317 built, and the match is against only the built files. C<--expect-fail> can
318 be used with C<--match> to search for a commit that adds files that match.
319
320 =item *
321
322 --test-build
323
324 Test that the build completes, without running any test case.
325
326 By default, if the build for the desired I<target> fails to complete,
327 F<bisect-runner.pl> reports a I<skip> back to C<git bisect>, the assumption
328 being that one wants to find a commit which changed state "builds && passes"
329 to "builds && fails". If instead one is interested in which commit broke the
330 build (possibly for particular F<Configure> options), use I<--test-build>
331 to treat a build failure as a failure, not a "skip".
332
333 Often this option isn't as useful as it first seems, because I<any> build
334 failure will be reported to C<git bisect> as a failure, not just the failure
335 that you're interested in. Generally, to debug a particular problem, it's
336 more useful to use a I<target> that builds properly at the point of interest,
337 and then a test case that runs C<make>. For example:
338
339     .../Porting/bisect.pl --start=perl-5.000 --end=perl-5.002 \
340         --expect-fail --force-manifest --target=miniperl make perl
341
342 will find the first revision capable of building L<DynaLoader> and then
343 F<perl>, without becoming confused by revisions where F<miniperl> won't
344 even link.
345
346 =item *
347
348 --force-manifest
349
350 By default, a build will "skip" if any files listed in F<MANIFEST> are not
351 present. Usually this is useful, as it avoids false-failures. However, there
352 are some long ranges of commits where listed files are missing, which can
353 cause a bisect to abort because all that remain are skipped revisions.
354
355 In these cases, particularly if the test case uses F<miniperl> and no modules,
356 it may be more useful to force the build to continue, even if files
357 F<MANIFEST> are missing.
358
359 =item *
360
361 --expect-pass [0|1]
362
363 C<--expect-pass=0> is equivalent to C<--expect-fail>. I<1> is the default.
364
365 =item *
366
367 --no-clean
368
369 Tell F<bisect-runner.pl> not to clean up after the build. This allows one
370 to use F<bisect-runner.pl> to build the current particular perl revision for
371 interactive testing, or for debugging F<bisect-runner.pl>.
372
373 Passing this to F<bisect.pl> will likely cause the bisect to fail badly.
374
375 =item *
376
377 --check-args
378
379 Validate the options and arguments, and exit silently if they are valid.
380
381 =item *
382
383 --usage
384
385 =item *
386
387 --help
388
389 =item *
390
391 -?
392
393 Display the usage information and exit.
394
395 =back
396
397 =cut
398
399 die "$0: Can't build $target" if defined $target && !grep {@targets} $target;
400
401 $j = "-j$j" if $j =~ /\A\d+\z/;
402
403 # Sadly, however hard we try, I don't think that it will be possible to build
404 # modules in ext/ on x86_64 Linux before commit e1666bf5602ae794 on 1999/12/29,
405 # which updated to MakeMaker 3.7, which changed from using a hard coded ld
406 # in the Makefile to $(LD). On x86_64 Linux the "linker" is gcc.
407
408 sub extract_from_file {
409     my ($file, $rx, $default) = @_;
410     open my $fh, '<', $file or die "Can't open $file: $!";
411     while (<$fh>) {
412         my @got = $_ =~ $rx;
413         return wantarray ? @got : $got[0]
414             if @got;
415     }
416     return $default if defined $default;
417     return;
418 }
419
420 sub edit_file {
421     my ($file, $munger) = @_;
422     local $/;
423     open my $fh, '<', $file or die "Can't open $file: $!";
424     my $orig = <$fh>;
425     die "Can't read $file: $!" unless defined $orig && close $fh;
426     my $new = $munger->($orig);
427     return if $new eq $orig;
428     open $fh, '>', $file or die "Can't open $file: $!";
429     print $fh $new or die "Can't print to $file: $!";
430     close $fh or die "Can't close $file: $!";
431 }
432
433 sub apply_patch {
434     my $patch = shift;
435
436     my ($file) = $patch =~ qr!^diff.*a/(\S+) b/\1!;
437     open my $fh, '|-', 'patch', '-p1' or die "Can't run patch: $!";
438     print $fh $patch;
439     return if close $fh;
440     print STDERR "Patch is <<'EOPATCH'\n${patch}EOPATCH\n";
441     die "Can't patch $file: $?, $!";
442 }
443
444 sub clean {
445     if ($options{clean}) {
446         # Needed, because files that are build products in this checked out
447         # version might be in git in the next desired version.
448         system 'git clean -dxf </dev/null';
449         # Needed, because at some revisions the build alters checked out files.
450         # (eg pod/perlapi.pod). Also undoes any changes to makedepend.SH
451         system 'git reset --hard HEAD </dev/null';
452     }
453 }
454
455 sub skip {
456     my $reason = shift;
457     clean();
458     warn "skipping - $reason";
459     exit 125;
460 }
461
462 sub report_and_exit {
463     my ($ret, $pass, $fail, $desc) = @_;
464
465     clean();
466
467     my $got = ($options{'expect-pass'} ? !$ret : $ret) ? 'good' : 'bad';
468     if ($ret) {
469         print "$got - $fail $desc\n";
470     } else {
471         print "$got - $pass $desc\n";
472     }
473
474     exit($got eq 'bad');
475 }
476
477 sub match_and_exit {
478     my $target = shift;
479     my $matches = 0;
480     my $re = qr/$match/;
481     my @files;
482
483     {
484         local $/ = "\0";
485         @files = defined $target ? `git ls-files -o -z`: `git ls-files -z`;
486         chomp @files;
487     }
488
489     foreach my $file (@files) {
490         open my $fh, '<', $file or die "Can't open $file: $!";
491         while (<$fh>) {
492             if ($_ =~ $re) {
493                 ++$matches;
494                 if (tr/\t\r\n -~\200-\377//c) {
495                     print "Binary file $file matches\n";
496                 } else {
497                     $_ .= "\n" unless /\n\z/;
498                     print "$file: $_";
499                 }
500             }
501         }
502         close $fh or die "Can't close $file: $!";
503     }
504     report_and_exit(!$matches,
505                     $matches == 1 ? '1 match for' : "$matches matches for",
506                     'no matches for', $match);
507 }
508
509 # Not going to assume that system perl is yet new enough to have autodie
510 system 'git clean -dxf </dev/null' and die;
511
512 if (!defined $target) {
513     match_and_exit() if $match;
514     $target = 'test_prep';
515 }
516
517 skip('no Configure - is this the //depot/perlext/Compiler branch?')
518     unless -f 'Configure';
519
520 # This changes to PERL_VERSION in 4d8076ea25903dcb in 1999
521 my $major
522     = extract_from_file('patchlevel.h',
523                         qr/^#define\s+(?:PERL_VERSION|PATCHLEVEL)\s+(\d+)\s/,
524                         0);
525
526 if ($major < 1) {
527     if (extract_from_file('Configure',
528                           qr/^          \*=\*\) echo "\$1" >> \$optdef;;$/)) {
529         # This is "        Spaces now allowed in -D command line options.",
530         # part of commit ecfc54246c2a6f42
531         apply_patch(<<'EOPATCH');
532 diff --git a/Configure b/Configure
533 index 3d3b38d..78ffe16 100755
534 --- a/Configure
535 +++ b/Configure
536 @@ -652,7 +777,8 @@ while test $# -gt 0; do
537                         echo "$me: use '-U symbol=', not '-D symbol='." >&2
538                         echo "$me: ignoring -D $1" >&2
539                         ;;
540 -               *=*) echo "$1" >> $optdef;;
541 +               *=*) echo "$1" | \
542 +                               sed -e "s/'/'\"'\"'/g" -e "s/=\(.*\)/='\1'/" >> $optdef;;
543                 *) echo "$1='define'" >> $optdef;;
544                 esac
545                 shift
546 EOPATCH
547     }
548     if (extract_from_file('Configure', qr/^if \$contains 'd_namlen' \$xinc\b/)) {
549         # Configure's original simple "grep" for d_namlen falls foul of the
550         # approach taken by the glibc headers:
551         # #ifdef _DIRENT_HAVE_D_NAMLEN
552         # # define _D_EXACT_NAMLEN(d) ((d)->d_namlen)
553         #
554         # where _DIRENT_HAVE_D_NAMLEN is not defined on Linux.
555         # This is also part of commit ecfc54246c2a6f42
556         apply_patch(<<'EOPATCH');
557 diff --git a/Configure b/Configure
558 index 3d3b38d..78ffe16 100755
559 --- a/Configure
560 +++ b/Configure
561 @@ -3935,7 +4045,8 @@ $rm -f try.c
562  
563  : see if the directory entry stores field length
564  echo " "
565 -if $contains 'd_namlen' $xinc >/dev/null 2>&1; then
566 +$cppstdin $cppflags $cppminus < "$xinc" > try.c
567 +if $contains 'd_namlen' try.c >/dev/null 2>&1; then
568         echo "Good, your directory entry keeps length information in d_namlen." >&4
569         val="$define"
570  else
571 EOPATCH
572     }
573 }
574
575 if ($major < 5 && extract_from_file('Configure',
576                                     qr!if \$cc \$ccflags try\.c -o try >/dev/null 2>&1; then!)) {
577     # Analogous to the more general fix of dfe9444ca7881e71
578     # Without this flags such as -m64 may not be passed to this compile, which
579     # results in a byteorder of '1234' instead of '12345678', which can then
580     # cause crashes.
581     
582     if (extract_from_file('Configure', qr/xxx_prompt=y/)) {
583         # 8e07c86ebc651fe9 or later
584         # ("This is my patch  patch.1n  for perl5.001.")
585         apply_patch(<<'EOPATCH');
586 diff --git a/Configure b/Configure
587 index 62249dd..c5c384e 100755
588 --- a/Configure
589 +++ b/Configure
590 @@ -8247,7 +8247,7 @@ main()
591  }
592  EOCP
593         xxx_prompt=y
594 -       if $cc $ccflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
595 +       if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
596                 dflt=`./try`
597                 case "$dflt" in
598                 [1-4][1-4][1-4][1-4]|12345678|87654321)
599 EOPATCH
600     } else {
601         apply_patch(<<'EOPATCH');
602 diff --git a/Configure b/Configure
603 index 53649d5..f1cd64a 100755
604 --- a/Configure
605 +++ b/Configure
606 @@ -6362,7 +6362,7 @@ main()
607         printf("\n");
608  }
609  EOCP
610 -       if $cc $ccflags try.c -o try >/dev/null 2>&1 ; then
611 +       if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 ; then
612                 dflt=`./try`
613                 case "$dflt" in
614                 ????|????????) echo "(The test program ran ok.)";;
615 EOPATCH
616     }
617 }
618
619 if ($major < 8 && !extract_from_file('Configure',
620                                     qr/^\t\tif test ! -t 0; then$/)) {
621     # Before dfe9444ca7881e71, Configure would refuse to run if stdin was not a
622     # tty. With that commit, the tty requirement was dropped for -de and -dE
623     # Commit aaeb8e512e8e9e14 dropped the tty requirement for -S
624     # For those older versions, it's probably easiest if we simply remove the
625     # sanity test.
626     edit_file('Configure', sub {
627                   my $code = shift;
628                   $code =~ s/test ! -t 0/test Perl = rules/;
629                   return $code;
630               });
631 }
632
633 if ($major == 8 || $major == 9) {
634     # Fix symbol detection to that of commit 373dfab3839ca168 if it's any
635     # intermediate version 5129fff43c4fe08c or later, as the intermediate
636     # versions don't work correctly on (at least) Sparc Linux.
637     # 5129fff43c4fe08c adds the first mention of mistrustnm.
638     # 373dfab3839ca168 removes the last mention of lc=""
639     edit_file('Configure', sub {
640                   my $code = shift;
641                   return $code
642                       if $code !~ /\btc="";/; # 373dfab3839ca168 or later
643                   return $code
644                       if $code !~ /\bmistrustnm\b/; # before 5129fff43c4fe08c
645                   my $fixed = <<'EOC';
646
647 : is a C symbol defined?
648 csym='tlook=$1;
649 case "$3" in
650 -v) tf=libc.tmp; tdc="";;
651 -a) tf=libc.tmp; tdc="[]";;
652 *) tlook="^$1\$"; tf=libc.list; tdc="()";;
653 esac;
654 tx=yes;
655 case "$reuseval-$4" in
656 true-) ;;
657 true-*) tx=no; eval "tval=\$$4"; case "$tval" in "") tx=yes;; esac;;
658 esac;
659 case "$tx" in
660 yes)
661         tval=false;
662         if $test "$runnm" = true; then
663                 if $contains $tlook $tf >/dev/null 2>&1; then
664                         tval=true;
665                 elif $test "$mistrustnm" = compile -o "$mistrustnm" = run; then
666                         echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
667                         $cc -o try $optimize $ccflags $ldflags try.c >/dev/null 2>&1 $libs && tval=true;
668                         $test "$mistrustnm" = run -a -x try && { $run ./try$_exe >/dev/null 2>&1 || tval=false; };
669                         $rm -f try$_exe try.c core core.* try.core;
670                 fi;
671         else
672                 echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
673                 $cc -o try $optimize $ccflags $ldflags try.c $libs >/dev/null 2>&1 && tval=true;
674                 $rm -f try$_exe try.c;
675         fi;
676         ;;
677 *)
678         case "$tval" in
679         $define) tval=true;;
680         *) tval=false;;
681         esac;
682         ;;
683 esac;
684 eval "$2=$tval"'
685
686 EOC
687                   $code =~ s/\n: is a C symbol defined\?\n.*?\neval "\$2=\$tval"'\n\n/$fixed/sm
688                       or die "substitution failed";
689                   return $code;
690               });
691 }
692
693 if ($major < 10 && extract_from_file('Configure', qr/^set malloc\.h i_malloc$/)) {
694     # This is commit 01d07975f7ef0e7d, trimmed, with $compile inlined as
695     # prior to bd9b35c97ad661cc Configure had the malloc.h test before the
696     # definition of $compile.
697     apply_patch(<<'EOPATCH');
698 diff --git a/Configure b/Configure
699 index 3d2e8b9..6ce7766 100755
700 --- a/Configure
701 +++ b/Configure
702 @@ -6743,5 +6743,22 @@ set d_dosuid
703  
704  : see if this is a malloc.h system
705 -set malloc.h i_malloc
706 -eval $inhdr
707 +: we want a real compile instead of Inhdr because some systems have a
708 +: malloc.h that just gives a compile error saying to use stdlib.h instead
709 +echo " "
710 +$cat >try.c <<EOCP
711 +#include <stdlib.h>
712 +#include <malloc.h>
713 +int main () { return 0; }
714 +EOCP
715 +set try
716 +if $cc $optimize $ccflags $ldflags -o try $* try.c $libs > /dev/null 2>&1; then
717 +    echo "<malloc.h> found." >&4
718 +    val="$define"
719 +else
720 +    echo "<malloc.h> NOT found." >&4
721 +    val="$undef"
722 +fi
723 +$rm -f try.c try
724 +set i_malloc
725 +eval $setvar
726  
727 EOPATCH
728 }
729
730 # Cwd.xs added in commit 0d2079faa739aaa9. Cwd.pm moved to ext/ 8 years later
731 # in commit 403f501d5b37ebf0
732 if ($major > 0 && <*/Cwd/Cwd.xs>) {
733     if ($major < 10 && !extract_from_file('Makefile.SH', qr/^extra_dep=''$/)) {
734         # The Makefile.PL for Unicode::Normalize needs
735         # lib/unicore/CombiningClass.pl. Even without a parallel build, we need
736         # a dependency to ensure that it builds. This is a variant of commit
737         # 9f3ef600c170f61e. Putting this for earlier versions gives us a spot
738         # on which to hang the edits below
739         apply_patch(<<'EOPATCH');
740 diff --git a/Makefile.SH b/Makefile.SH
741 index f61d0db..6097954 100644
742 --- a/Makefile.SH
743 +++ b/Makefile.SH
744 @@ -155,10 +155,20 @@ esac
745  
746  : Prepare dependency lists for Makefile.
747  dynamic_list=' '
748 +extra_dep=''
749  for f in $dynamic_ext; do
750      : the dependency named here will never exist
751        base=`echo "$f" | sed 's/.*\///'`
752 -    dynamic_list="$dynamic_list lib/auto/$f/$base.$dlext"
753 +    this_target="lib/auto/$f/$base.$dlext"
754 +    dynamic_list="$dynamic_list $this_target"
755 +
756 +    : Parallel makes reveal that we have some interdependencies
757 +    case $f in
758 +       Math/BigInt/FastCalc) extra_dep="$extra_dep
759 +$this_target: lib/auto/List/Util/Util.$dlext" ;;
760 +       Unicode/Normalize) extra_dep="$extra_dep
761 +$this_target: lib/unicore/CombiningClass.pl" ;;
762 +    esac
763  done
764  
765  static_list=' '
766 @@ -987,2 +997,9 @@ n_dummy $(nonxs_ext):       miniperl$(EXE_EXT) preplibrary $(DYNALOADER) FORCE
767         @$(LDLIBPTH) sh ext/util/make_ext nonxs $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL)
768 +!NO!SUBS!
769 +
770 +$spitshell >>Makefile <<EOF
771 +$extra_dep
772 +EOF
773 +
774 +$spitshell >>Makefile <<'!NO!SUBS!'
775  
776 EOPATCH
777     }
778     if ($major < 14) {
779         # Commits dc0655f797469c47 and d11a62fe01f2ecb2
780         edit_file('Makefile.SH', sub {
781                       my $code = shift;
782                       foreach my $ext (qw(Encode SDBM_File)) {
783                           next if $code =~ /\b$ext\) extra_dep=/s;
784                           $code =~ s!(\) extra_dep="\$extra_dep
785 \$this_target: .*?" ;;)
786 (    esac
787 )!$1
788         $ext) extra_dep="\$extra_dep
789 \$this_target: lib/auto/Cwd/Cwd.\$dlext" ;;
790 $2!;
791                       }
792                       return $code;
793                   });
794     }
795 }
796 if ($major == 7) {
797     # Remove commits 9fec149bb652b6e9 and 5bab1179608f81d8, which add/amend
798     # rules to automatically run regen scripts that rebuild C headers. These
799     # cause problems because a git checkout doesn't preserve relative file
800     # modification times, hence the regen scripts may fire. This will obscure
801     # whether the repository had the correct generated headers checked in.
802     # Also, the dependency rules for running the scripts were not correct,
803     # which could cause spurious re-builds on re-running make, and can cause
804     # complete build failures for a parallel make.
805     if (extract_from_file('Makefile.SH',
806                           qr/Writing it this way gives make a big hint to always run opcode\.pl before/)) {
807         system 'git show 70c6e6715e8fec53 | patch -p1'
808             and die;
809     } elsif (extract_from_file('Makefile.SH',
810                                qr/^opcode\.h opnames\.h pp_proto\.h pp\.sym: opcode\.pl$/)) {
811         system 'git show 9fec149bb652b6e9 | patch -p1 -R'
812             and die;
813     }
814 }
815
816 # There was a bug in makedepend.SH which was fixed in version 96a8704c.
817 # Symptom was './makedepend: 1: Syntax error: Unterminated quoted string'
818 # Remove this if you're actually bisecting a problem related to makedepend.SH
819 system 'git show blead:makedepend.SH > makedepend.SH </dev/null' and die;
820
821 if ($^O eq 'freebsd') {
822     # There are rather too many version-specific FreeBSD hints fixes to patch
823     # individually. Also, more than once the FreeBSD hints file has been
824     # written in what turned out to be a rather non-future-proof style,
825     # with case statements treating the most recent version as the exception,
826     # instead of treating previous versions' behaviour explicitly and changing
827     # the default to cater for the current behaviour. (As strangely, future
828     # versions inherit the current behaviour.)
829     system 'git show blead:hints/freebsd.sh > hints/freebsd.sh </dev/null'
830       and die;
831
832     if ($major < 2) {
833         # 5.002 Configure and later have code to
834         #
835         # : Try to guess additional flags to pick up local libraries.
836         #
837         # which will automatically add --L/usr/local/lib because libpth
838         # contains /usr/local/lib
839         #
840         # Without it, if Configure finds libraries in /usr/local/lib (eg
841         # libgdbm.so) and adds them to the compiler commandline (as -lgdbm),
842         # then the link will fail. We can't fix this up in config.sh because
843         # the link will *also* fail in the test compiles that Configure does
844         # (eg $inlibc) which makes Configure get all sorts of things
845         # wrong. :-( So bodge it here.
846         #
847         # Possibly other platforms will need something similar. (if they
848         # have "wanted" libraries in /usr/local/lib, but the compiler
849         # doesn't default to putting that directory in its link path)
850         apply_patch(<<'EOPATCH');
851 --- perl2/hints/freebsd.sh.orig 2011-10-05 16:44:55.000000000 +0200
852 +++ perl2/hints/freebsd.sh      2011-10-05 16:45:52.000000000 +0200
853 @@ -125,7 +125,7 @@
854          else
855              libpth="/usr/lib /usr/local/lib"
856              glibpth="/usr/lib /usr/local/lib"
857 -            ldflags="-Wl,-E "
858 +            ldflags="-Wl,-E -L/usr/local/lib "
859              lddlflags="-shared "
860          fi
861          cccdlflags='-DPIC -fPIC'
862 @@ -133,7 +133,7 @@
863  *)
864         libpth="/usr/lib /usr/local/lib"
865         glibpth="/usr/lib /usr/local/lib"
866 -       ldflags="-Wl,-E "
867 +       ldflags="-Wl,-E -L/usr/local/lib "
868          lddlflags="-shared "
869          cccdlflags='-DPIC -fPIC'
870         ;;
871 EOPATCH
872     }
873 } elsif ($^O eq 'darwin') {
874     if ($major < 8) {
875         my $faking_it;
876         # We can't build on darwin without some of the data in the hints file.
877         foreach ('ext/DynaLoader/dl_dyld.xs', 'hints/darwin.sh') {
878             next if -f $_;
879             ++$faking_it;
880             # Probably less surprising to use the earliest version of
881             # hints/darwin.sh and then edit in place just below, than use
882             # blead's version, as that would create a discontinuity at
883             # f556e5b971932902 - before it, hints bugs would be "fixed", after
884             # it they'd resurface. This way, we should give the illusion of
885             # monotonic bug fixing.
886             system "git show f556e5b971932902:$_ >$_"
887                 and die "while attempting to extract $_";
888         }
889         if ($faking_it) {
890             apply_patch(<<'EOPATCH');
891 diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
892 --- a/ext/DynaLoader/dl_dyld.xs~        2011-10-11 21:41:27.000000000 +0100
893 +++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 21:42:20.000000000 +0100
894 @@ -41,6 +41,35 @@
895  #include "perl.h"
896  #include "XSUB.h"
897  
898 +#ifndef pTHX
899 +#  define pTHX         void
900 +#  define pTHX_
901 +#endif
902 +#ifndef aTHX
903 +#  define aTHX
904 +#  define aTHX_
905 +#endif
906 +#ifndef dTHX
907 +#  define dTHXa(a)     extern int Perl___notused(void)
908 +#  define dTHX         extern int Perl___notused(void)
909 +#endif
910 +
911 +#ifndef Perl_form_nocontext
912 +#  define Perl_form_nocontext form
913 +#endif
914 +
915 +#ifndef Perl_warn_nocontext
916 +#  define Perl_warn_nocontext warn
917 +#endif
918 +
919 +#ifndef PTR2IV
920 +#  define PTR2IV(p)    (IV)(p)
921 +#endif
922 +
923 +#ifndef get_av
924 +#  define get_av perl_get_av
925 +#endif
926 +
927  #define DL_LOADONCEONLY
928  
929  #include "dlutils.c"   /* SaveError() etc      */
930 @@ -185,7 +191,7 @@
931      CODE:
932      DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
933      if (flags & 0x01)
934 -       Perl_warn(aTHX_ "Can't make loaded symbols global on this platform while loading %s",filename);
935 +       Perl_warn_nocontext("Can't make loaded symbols global on this platform while loading %s",filename);
936      RETVAL = dlopen(filename, mode) ;
937      DLDEBUG(2,PerlIO_printf(Perl_debug_log, " libref=%x\n", RETVAL));
938      ST(0) = sv_newmortal() ;
939 EOPATCH
940             if ($major < 4 && !extract_from_file('util.c', qr/^form/m)) {
941                 apply_patch(<<'EOPATCH');
942 diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
943 --- a/ext/DynaLoader/dl_dyld.xs~        2011-10-11 21:56:25.000000000 +0100
944 +++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 22:00:00.000000000 +0100
945 @@ -60,6 +60,18 @@
946  #  define get_av perl_get_av
947  #endif
948  
949 +static char *
950 +form(char *pat, ...)
951 +{
952 +    char *retval;
953 +    va_list args;
954 +    va_start(args, pat);
955 +    vasprintf(&retval, pat, &args);
956 +    va_end(args);
957 +    SAVEFREEPV(retval);
958 +    return retval;
959 +}
960 +
961  #define DL_LOADONCEONLY
962  
963  #include "dlutils.c"   /* SaveError() etc      */
964 EOPATCH
965             }
966         }
967
968         edit_file('hints/darwin.sh', sub {
969                       my $code = shift;
970                       # Part of commit 8f4f83badb7d1ba9, which mostly undoes
971                       # commit 0511a818910f476c.
972                       $code =~ s/^cppflags='-traditional-cpp';$/cppflags="\${cppflags} -no-cpp-precomp"/m;
973                       # commit 14c11978e9b52e08/803bb6cc74d36a3f
974                       # Without this, code in libperl.bundle links against op.o
975                       # in preference to opmini.o on the linker command line,
976                       # and hence miniperl tries to use File::Glob instead of
977                       # csh
978                       $code =~ s/^(lddlflags=)/ldflags="\${ldflags} -flat_namespace"\n$1/m;
979                       # f556e5b971932902 also patches Makefile.SH with some
980                       # special case code to deal with useshrplib for darwin.
981                       # Given that post 5.8.0 the darwin hints default was
982                       # changed to false, and it would be very complex to splice
983                       # in that code in various versions of Makefile.SH back
984                       # to 5.002, lets just turn it off.
985                       $code =~ s/^useshrplib='true'/useshrplib='false'/m
986                           if $faking_it;
987                       return $code;
988                   });
989     }
990 } elsif ($^O eq 'netbsd') {
991     if ($major < 6) {
992         # These are part of commit 099685bc64c7dbce
993         edit_file('hints/netbsd.sh', sub {
994                       my $code = shift;
995                       my $fixed = <<'EOC';
996 case "$osvers" in
997 0.9|0.8*)
998         usedl="$undef"
999         ;;
1000 *)
1001         if [ -f /usr/libexec/ld.elf_so ]; then
1002                 d_dlopen=$define
1003                 d_dlerror=$define
1004                 ccdlflags="-Wl,-E -Wl,-R${PREFIX}/lib $ccdlflags"
1005                 cccdlflags="-DPIC -fPIC $cccdlflags"
1006                 lddlflags="--whole-archive -shared $lddlflags"
1007         elif [ "`uname -m`" = "pmax" ]; then
1008 # NetBSD 1.3 and 1.3.1 on pmax shipped an `old' ld.so, which will not work.
1009                 d_dlopen=$undef
1010         elif [ -f /usr/libexec/ld.so ]; then
1011                 d_dlopen=$define
1012                 d_dlerror=$define
1013                 ccdlflags="-Wl,-R${PREFIX}/lib $ccdlflags"
1014 # we use -fPIC here because -fpic is *NOT* enough for some of the
1015 # extensions like Tk on some netbsd platforms (the sparc is one)
1016                 cccdlflags="-DPIC -fPIC $cccdlflags"
1017                 lddlflags="-Bforcearchive -Bshareable $lddlflags"
1018         else
1019                 d_dlopen=$undef
1020         fi
1021         ;;
1022 esac
1023 EOC
1024                       $code =~ s/^case "\$osvers" in\n0\.9\|0\.8.*?^esac\n/$fixed/ms;
1025                       return $code;
1026                   });
1027         if (!extract_from_file('unixish.h',
1028                                qr/defined\(NSIG\).*defined\(__NetBSD__\)/)) {
1029             apply_patch(<<'EOPATCH')
1030 diff --git a/unixish.h b/unixish.h
1031 index 2a6cbcd..eab2de1 100644
1032 --- a/unixish.h
1033 +++ b/unixish.h
1034 @@ -89,7 +89,7 @@
1035   */
1036  /* #define ALTERNATE_SHEBANG "#!" / **/
1037  
1038 -#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
1039 +#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) || defined(__NetBSD__)
1040  # include <signal.h>
1041  #endif
1042  
1043 EOPATCH
1044         }
1045     }
1046 } elsif ($^O eq 'openbsd') {
1047     if (!-f 'hints/openbsd.sh') {
1048         system 'git show 43051805d53a3e4c:hints/openbsd.sh > hints/openbsd.sh'
1049           and die;
1050     }
1051
1052     if ($major < 8) {
1053         my $which = extract_from_file('hints/openbsd.sh',
1054                                       qr/# from (2\.8|3\.1) onwards/,
1055                                       '');
1056         if ($which eq '') {
1057             my $was = extract_from_file('hints/openbsd.sh',
1058                                         qr/(lddlflags="(?:-Bforcearchive )?-Bshareable)/);
1059             # This is commit 154d43cbcf57271c and parts of 5c75dbfa77b0949c
1060             # and 29b5585702e5e025
1061             apply_patch(sprintf <<'EOPATCH', $was);
1062 diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1063 index a7d8bf2..5b79709 100644
1064 --- a/hints/openbsd.sh
1065 +++ b/hints/openbsd.sh
1066 @@ -37,7 +37,25 @@ OpenBSD.alpha|OpenBSD.mips|OpenBSD.powerpc|OpenBSD.vax)
1067         # we use -fPIC here because -fpic is *NOT* enough for some of the
1068         # extensions like Tk on some OpenBSD platforms (ie: sparc)
1069         cccdlflags="-DPIC -fPIC $cccdlflags"
1070 -       %s $lddlflags"
1071 +       case "$osvers" in
1072 +       [01].*|2.[0-7]|2.[0-7].*)
1073 +               lddlflags="-Bshareable $lddlflags"
1074 +               ;;
1075 +       2.[8-9]|3.0)
1076 +               ld=${cc:-cc}
1077 +               lddlflags="-shared -fPIC $lddlflags"
1078 +               ;;
1079 +       *) # from 3.1 onwards
1080 +               ld=${cc:-cc}
1081 +               lddlflags="-shared -fPIC $lddlflags"
1082 +               libswanted=`echo $libswanted | sed 's/ dl / /'`
1083 +               ;;
1084 +       esac
1085 +
1086 +       # We need to force ld to export symbols on ELF platforms.
1087 +       # Without this, dlopen() is crippled.
1088 +       ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1089 +       test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1090         ;;
1091  esac
1092  
1093 EOPATCH
1094         } elsif ($which eq '2.8') {
1095             # This is parts of 5c75dbfa77b0949c and 29b5585702e5e025, and
1096             # possibly eb9cd59d45ad2908
1097             my $was = extract_from_file('hints/openbsd.sh',
1098                                         qr/lddlflags="(-shared(?: -fPIC)?) \$lddlflags"/);
1099
1100             apply_patch(sprintf <<'EOPATCH', $was);
1101 --- a/hints/openbsd.sh  2011-10-21 17:25:20.000000000 +0200
1102 +++ b/hints/openbsd.sh  2011-10-21 16:58:43.000000000 +0200
1103 @@ -44,11 +44,21 @@
1104         [01].*|2.[0-7]|2.[0-7].*)
1105                 lddlflags="-Bshareable $lddlflags"
1106                 ;;
1107 -       *) # from 2.8 onwards
1108 +       2.[8-9]|3.0)
1109                 ld=${cc:-cc}
1110 -               lddlflags="%s $lddlflags"
1111 +               lddlflags="-shared -fPIC $lddlflags"
1112 +               ;;
1113 +       *) # from 3.1 onwards
1114 +               ld=${cc:-cc}
1115 +               lddlflags="-shared -fPIC $lddlflags"
1116 +               libswanted=`echo $libswanted | sed 's/ dl / /'`
1117                 ;;
1118         esac
1119 +
1120 +       # We need to force ld to export symbols on ELF platforms.
1121 +       # Without this, dlopen() is crippled.
1122 +       ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1123 +       test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1124         ;;
1125  esac
1126  
1127 EOPATCH
1128         } elsif ($which eq '3.1'
1129                 && !extract_from_file('hints/openbsd.sh',
1130                                      qr/We need to force ld to export symbols on ELF platforms/)) {
1131             # This is part of 29b5585702e5e025
1132             apply_patch(<<'EOPATCH');
1133 diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1134 index c6b6bc9..4839d04 100644
1135 --- a/hints/openbsd.sh
1136 +++ b/hints/openbsd.sh
1137 @@ -54,6 +54,11 @@ alpha-2.[0-8]|mips-*|vax-*|powerpc-2.[0-7]|m88k-*)
1138                 libswanted=`echo $libswanted | sed 's/ dl / /'`
1139                 ;;
1140         esac
1141 +
1142 +       # We need to force ld to export symbols on ELF platforms.
1143 +       # Without this, dlopen() is crippled.
1144 +       ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1145 +       test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1146         ;;
1147  esac
1148  
1149 EOPATCH
1150         }
1151     }
1152     if ($major < 4) {
1153         my $bad;
1154         # Need changes from commit a6e633defa583ad5.
1155         # Commits c07a80fdfe3926b5 and f82b3d4130164d5f changed the same part
1156         # of perl.h
1157
1158         if (extract_from_file('perl.h',
1159                               qr/^#ifdef HAS_GETPGRP2$/)) {
1160             $bad = <<'EOBAD';
1161 ***************
1162 *** 57,71 ****
1163   #define TAINT_PROPER(s)       if (tainting) taint_proper(no_security, s)
1164   #define TAINT_ENV()   if (tainting) taint_env()
1165   
1166 ! #ifdef HAS_GETPGRP2
1167 ! #   ifndef HAS_GETPGRP
1168 ! #     define HAS_GETPGRP
1169 ! #   endif
1170 ! #endif
1171
1172 ! #ifdef HAS_SETPGRP2
1173 ! #   ifndef HAS_SETPGRP
1174 ! #     define HAS_SETPGRP
1175 ! #   endif
1176   #endif
1177   
1178 EOBAD
1179         } elsif (extract_from_file('perl.h',
1180                                    qr/Gack, you have one but not both of getpgrp2/)) {
1181             $bad = <<'EOBAD';
1182 ***************
1183 *** 56,76 ****
1184   #define TAINT_PROPER(s)       if (tainting) taint_proper(no_security, s)
1185   #define TAINT_ENV()   if (tainting) taint_env()
1186   
1187 ! #if defined(HAS_GETPGRP2) && defined(HAS_SETPGRP2)
1188 ! #   define getpgrp getpgrp2
1189 ! #   define setpgrp setpgrp2
1190 ! #   ifndef HAS_GETPGRP
1191 ! #     define HAS_GETPGRP
1192 ! #   endif
1193 ! #   ifndef HAS_SETPGRP
1194 ! #     define HAS_SETPGRP
1195 ! #   endif
1196 ! #   ifndef USE_BSDPGRP
1197 ! #     define USE_BSDPGRP
1198 ! #   endif
1199 ! #else
1200 ! #   if defined(HAS_GETPGRP2) || defined(HAS_SETPGRP2)
1201 !       #include "Gack, you have one but not both of getpgrp2() and setpgrp2()."
1202 ! #   endif
1203   #endif
1204   
1205 EOBAD
1206         } elsif (extract_from_file('perl.h',
1207                                    qr/^#ifdef USE_BSDPGRP$/)) {
1208             $bad = <<'EOBAD'
1209 ***************
1210 *** 91,116 ****
1211   #define TAINT_PROPER(s)       if (tainting) taint_proper(no_security, s)
1212   #define TAINT_ENV()   if (tainting) taint_env()
1213   
1214 ! #ifdef USE_BSDPGRP
1215 ! #   ifdef HAS_GETPGRP
1216 ! #       define BSD_GETPGRP(pid) getpgrp((pid))
1217 ! #   endif
1218 ! #   ifdef HAS_SETPGRP
1219 ! #       define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp))
1220 ! #   endif
1221 ! #else
1222 ! #   ifdef HAS_GETPGRP2
1223 ! #       define BSD_GETPGRP(pid) getpgrp2((pid))
1224 ! #       ifndef HAS_GETPGRP
1225 ! #         define HAS_GETPGRP
1226 ! #     endif
1227 ! #   endif
1228 ! #   ifdef HAS_SETPGRP2
1229 ! #       define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp))
1230 ! #       ifndef HAS_SETPGRP
1231 ! #         define HAS_SETPGRP
1232 ! #     endif
1233 ! #   endif
1234   #endif
1235   
1236   #ifndef _TYPES_               /* If types.h defines this it's easy. */
1237 EOBAD
1238         }
1239         if ($bad) {
1240             apply_patch(<<"EOPATCH");
1241 *** a/perl.h    2011-10-21 09:46:12.000000000 +0200
1242 --- b/perl.h    2011-10-21 09:46:12.000000000 +0200
1243 $bad--- 91,144 ----
1244   #define TAINT_PROPER(s)       if (tainting) taint_proper(no_security, s)
1245   #define TAINT_ENV()   if (tainting) taint_env()
1246   
1247 ! /* XXX All process group stuff is handled in pp_sys.c.  Should these 
1248 !    defines move there?  If so, I could simplify this a lot. --AD  9/96.
1249 ! */
1250 ! /* Process group stuff changed from traditional BSD to POSIX.
1251 !    perlfunc.pod documents the traditional BSD-style syntax, so we'll
1252 !    try to preserve that, if possible.
1253 ! */
1254 ! #ifdef HAS_SETPGID
1255 ! #  define BSD_SETPGRP(pid, pgrp)      setpgid((pid), (pgrp))
1256 ! #else
1257 ! #  if defined(HAS_SETPGRP) && defined(USE_BSD_SETPGRP)
1258 ! #    define BSD_SETPGRP(pid, pgrp)    setpgrp((pid), (pgrp))
1259 ! #  else
1260 ! #    ifdef HAS_SETPGRP2  /* DG/UX */
1261 ! #      define BSD_SETPGRP(pid, pgrp)  setpgrp2((pid), (pgrp))
1262 ! #    endif
1263 ! #  endif
1264 ! #endif
1265 ! #if defined(BSD_SETPGRP) && !defined(HAS_SETPGRP)
1266 ! #  define HAS_SETPGRP  /* Well, effectively it does . . . */
1267 ! #endif
1268
1269 ! /* getpgid isn't POSIX, but at least Solaris and Linux have it, and it makes
1270 !     our life easier :-) so we'll try it.
1271 ! */
1272 ! #ifdef HAS_GETPGID
1273 ! #  define BSD_GETPGRP(pid)            getpgid((pid))
1274 ! #else
1275 ! #  if defined(HAS_GETPGRP) && defined(USE_BSD_GETPGRP)
1276 ! #    define BSD_GETPGRP(pid)          getpgrp((pid))
1277 ! #  else
1278 ! #    ifdef HAS_GETPGRP2  /* DG/UX */
1279 ! #      define BSD_GETPGRP(pid)                getpgrp2((pid))
1280 ! #    endif
1281 ! #  endif
1282 ! #endif
1283 ! #if defined(BSD_GETPGRP) && !defined(HAS_GETPGRP)
1284 ! #  define HAS_GETPGRP  /* Well, effectively it does . . . */
1285 ! #endif
1286
1287 ! /* These are not exact synonyms, since setpgrp() and getpgrp() may 
1288 !    have different behaviors, but perl.h used to define USE_BSDPGRP
1289 !    (prior to 5.003_05) so some extension might depend on it.
1290 ! */
1291 ! #if defined(USE_BSD_SETPGRP) || defined(USE_BSD_GETPGRP)
1292 ! #  ifndef USE_BSDPGRP
1293 ! #    define USE_BSDPGRP
1294 ! #  endif
1295   #endif
1296   
1297   #ifndef _TYPES_               /* If types.h defines this it's easy. */
1298 EOPATCH
1299         }
1300     }
1301     if ($major < 3 && !extract_from_file('pp_sys.c', qr/BSD_GETPGRP/)) {
1302         # Part of commit c3293030fd1b7489
1303         apply_patch(<<'EOPATCH');
1304 diff --git a/pp_sys.c b/pp_sys.c
1305 index 4608a2a..f0c9d1d 100644
1306 --- a/pp_sys.c
1307 +++ b/pp_sys.c
1308 @@ -2903,8 +2903,8 @@ PP(pp_getpgrp)
1309         pid = 0;
1310      else
1311         pid = SvIVx(POPs);
1312 -#ifdef USE_BSDPGRP
1313 -    value = (I32)getpgrp(pid);
1314 +#ifdef BSD_GETPGRP
1315 +    value = (I32)BSD_GETPGRP(pid);
1316  #else
1317      if (pid != 0)
1318         DIE("POSIX getpgrp can't take an argument");
1319 @@ -2933,8 +2933,8 @@ PP(pp_setpgrp)
1320      }
1321  
1322      TAINT_PROPER("setpgrp");
1323 -#ifdef USE_BSDPGRP
1324 -    SETi( setpgrp(pid, pgrp) >= 0 );
1325 +#ifdef BSD_SETPGRP
1326 +    SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
1327  #else
1328      if ((pgrp != 0) || (pid != 0)) {
1329         DIE("POSIX setpgrp can't take an argument");
1330 EOPATCH
1331     }
1332 } elsif ($^O eq 'linux') {
1333     if ($major < 1) {
1334         # sparc linux seems to need the -Dbool=char -DHAS_BOOL part of
1335         # perl5.000 patch.0n: [address Configure and build issues]
1336         edit_file('hints/linux.sh', sub {
1337                       my $code = shift;
1338                       $code =~ s!-I/usr/include/bsd!-Dbool=char -DHAS_BOOL!g;
1339                       return $code;
1340                   });
1341     }
1342
1343     if ($major <= 9) {
1344         if (`uname -sm` =~ qr/^Linux sparc/) {
1345             if (extract_from_file('hints/linux.sh', qr/sparc-linux/)) {
1346                 # Be sure to use -fPIC not -fpic on Linux/SPARC
1347                 system 'git show f6527d0ef0c13ad4 | patch -p1'
1348                     and die;
1349             } elsif(!extract_from_file('hints/linux.sh', qr/^sparc-linux\)$/)) {
1350                 open my $fh, '>>', 'hints/linux.sh'
1351                     or die "Can't open hints/linux.sh: $!";
1352                 print $fh <<'EOT' or die $!;
1353
1354 case "`uname -m`" in
1355 sparc*)
1356         case "$cccdlflags" in
1357         *-fpic*) cccdlflags="`echo $cccdlflags|sed 's/-fpic/-fPIC/'`" ;;
1358         *)       cccdlflags="$cccdlflags -fPIC" ;;
1359         esac
1360         ;;
1361 esac
1362 EOT
1363                 close $fh or die "Can't close hints/linux.sh: $!";
1364             }
1365         }
1366     }
1367 }
1368
1369 if ($major < 10) {
1370     if (!extract_from_file('ext/DB_File/DB_File.xs',
1371                            qr!^#else /\* Berkeley DB Version > 2 \*/$!)) {
1372         # This DB_File.xs is really too old to patch up.
1373         # Skip DB_File, unless we're invoked with an explicit -Unoextensions
1374         if (!exists $defines{noextensions}) {
1375             $defines{noextensions} = 'DB_File';
1376         } elsif (defined $defines{noextensions}) {
1377             $defines{noextensions} .= ' DB_File';
1378         }
1379     } elsif (!extract_from_file('ext/DB_File/DB_File.xs',
1380                                 qr/^#ifdef AT_LEAST_DB_4_1$/)) {
1381         # This line is changed by commit 3245f0580c13b3ab
1382         my $line = extract_from_file('ext/DB_File/DB_File.xs',
1383                                      qr/^(        status = \(?RETVAL->dbp->open\)?\(RETVAL->dbp, name, NULL, RETVAL->type, $)/);
1384         apply_patch(<<"EOPATCH");
1385 diff --git a/ext/DB_File/DB_File.xs b/ext/DB_File/DB_File.xs
1386 index 489ba96..fba8ded 100644
1387 --- a/ext/DB_File/DB_File.xs
1388 +++ b/ext/DB_File/DB_File.xs
1389 \@\@ -183,4 +187,8 \@\@
1390  #endif
1391  
1392 +#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
1393 +#    define AT_LEAST_DB_4_1
1394 +#endif
1395 +
1396  /* map version 2 features & constants onto their version 1 equivalent */
1397  
1398 \@\@ -1334,7 +1419,12 \@\@ SV *   sv ;
1399  #endif
1400  
1401 +#ifdef AT_LEAST_DB_4_1
1402 +        status = (RETVAL->dbp->open)(RETVAL->dbp, NULL, name, NULL, RETVAL->type, 
1403 +                               Flags, mode) ; 
1404 +#else
1405  $line
1406                                 Flags, mode) ; 
1407 +#endif
1408         /* printf("open returned %d %s\\n", status, db_strerror(status)) ; */
1409  
1410 EOPATCH
1411     }
1412 }
1413
1414 # if Encode is not needed for the test, you can speed up the bisect by
1415 # excluding it from the runs with -Dnoextensions=Encode
1416 # ccache is an easy win. Remove it if it causes problems.
1417 # Commit 1cfa4ec74d4933da adds ignore_versioned_solibs to Configure, and sets it
1418 # to true in hints/linux.sh
1419 # On dromedary, from that point on, Configure (by default) fails to find any
1420 # libraries, because it scans /usr/local/lib /lib /usr/lib, which only contain
1421 # versioned libraries. Without -lm, the build fails.
1422 # Telling /usr/local/lib64 /lib64 /usr/lib64 works from that commit onwards,
1423 # until commit faae14e6e968e1c0 adds it to the hints.
1424 # However, prior to 1cfa4ec74d4933da telling Configure the truth doesn't work,
1425 # because it will spot versioned libraries, pass them to the compiler, and then
1426 # bail out pretty early on. Configure won't let us override libswanted, but it
1427 # will let us override the entire libs list.
1428
1429 unless (extract_from_file('Configure', 'ignore_versioned_solibs')) {
1430     # Before 1cfa4ec74d4933da, so force the libs list.
1431
1432     my @libs;
1433     # This is the current libswanted list from Configure, less the libs removed
1434     # by current hints/linux.sh
1435     foreach my $lib (qw(sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld
1436                         ld sun m crypt sec util c cposix posix ucb BSD)) {
1437         foreach my $dir (@paths) {
1438             next unless -f "$dir/lib$lib.so";
1439             push @libs, "-l$lib";
1440             last;
1441         }
1442     }
1443     $defines{libs} = \@libs unless exists $defines{libs};
1444 }
1445
1446 $defines{usenm} = undef
1447     if $major < 2 && !exists $defines{usenm};
1448
1449 my (@missing, @created_dirs);
1450
1451 if ($options{'force-manifest'}) {
1452     open my $fh, '<', 'MANIFEST'
1453         or die "Could not open MANIFEST: $!";
1454     while (<$fh>) {
1455         next unless /^(\S+)/;
1456         # -d is special case needed (at least) between 27332437a2ed1941 and
1457         # bf3d9ec563d25054^ inclusive, as manifest contains ext/Thread/Thread
1458         push @missing, $1
1459             unless -f $1 || -d $1;
1460     }
1461     close $fh or die "Can't close MANIFEST: $!";
1462
1463     foreach my $pathname (@missing) {
1464         my @parts = split '/', $pathname;
1465         my $leaf = pop @parts;
1466         my $path = '.';
1467         while (@parts) {
1468             $path .= '/' . shift @parts;
1469             next if -d $path;
1470             mkdir $path, 0700 or die "Can't create $path: $!";
1471             unshift @created_dirs, $path;
1472         }
1473         open $fh, '>', $pathname or die "Can't open $pathname: $!";
1474         close $fh or die "Can't close $pathname: $!";
1475         chmod 0, $pathname or die "Can't chmod 0 $pathname: $!";
1476     }
1477 }
1478
1479 my @ARGS = '-dEs';
1480 foreach my $key (sort keys %defines) {
1481     my $val = $defines{$key};
1482     if (ref $val) {
1483         push @ARGS, "-D$key=@$val";
1484     } elsif (!defined $val) {
1485         push @ARGS, "-U$key";
1486     } elsif (!length $val) {
1487         push @ARGS, "-D$key";
1488     } else {
1489         $val = "" if $val eq "\0";
1490         push @ARGS, "-D$key=$val";
1491     }
1492 }
1493 push @ARGS, map {"-A$_"} @{$options{A}};
1494
1495 # </dev/null because it seems that some earlier versions of Configure can
1496 # call commands in a way that now has them reading from stdin (and hanging)
1497 my $pid = fork;
1498 die "Can't fork: $!" unless defined $pid;
1499 if (!$pid) {
1500     open STDIN, '<', '/dev/null';
1501     # If a file in MANIFEST is missing, Configure asks if you want to
1502     # continue (the default being 'n'). With stdin closed or /dev/null,
1503     # it exits immediately and the check for config.sh below will skip.
1504     exec './Configure', @ARGS;
1505     die "Failed to start Configure: $!";
1506 }
1507 waitpid $pid, 0
1508     or die "wait for Configure, pid $pid failed: $!";
1509
1510 # Emulate noextensions if Configure doesn't support it.
1511 if (-f 'config.sh') {
1512     if ($major < 10 && $defines{noextensions}) {
1513         edit_file('config.sh', sub {
1514                       my @lines = split /\n/, shift;
1515                       my @ext = split /\s+/, $defines{noextensions};
1516                       foreach (@lines) {
1517                           next unless /^extensions=/ || /^dynamic_ext/;
1518                           foreach my $ext (@ext) {
1519                               s/\b$ext( )?\b/$1/;
1520                           }
1521                       }
1522                       return join "\n", @lines;
1523                   });
1524     }
1525     if ($major < 4 && !extract_from_file('config.sh', qr/^trnl=/)) {
1526         # This seems to be necessary to avoid makedepend becoming confused,
1527         # and hanging on stdin. Seems that the code after
1528         # make shlist || ...here... is never run.
1529         edit_file('makedepend.SH', sub {
1530                       my $code = shift;
1531                       $code =~ s/^trnl='\$trnl'$/trnl='\\n'/m;
1532                       return $code;
1533                   });
1534     }
1535
1536     system './Configure -S </dev/null' and die;
1537 }
1538
1539 if ($target =~ /config\.s?h/) {
1540     match_and_exit($target) if $match && -f $target;
1541     report_and_exit(!-f $target, 'could build', 'could not build', $target)
1542         if $options{'test-build'};
1543
1544     my $ret = system @ARGV;
1545     report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
1546 } elsif (!-f 'config.sh') {
1547     # Skip if something went wrong with Configure
1548
1549     skip('could not build config.sh');
1550 }
1551
1552 # This is probably way too paranoid:
1553 if (@missing) {
1554     my @errors;
1555     require Fcntl;
1556     foreach my $file (@missing) {
1557         my (undef, undef, $mode, undef, undef, undef, undef, $size)
1558             = stat $file;
1559         if (!defined $mode) {
1560             push @errors, "Added file $file has been deleted by Configure";
1561             next;
1562         }
1563         if (Fcntl::S_IMODE($mode) != 0) {
1564             push @errors,
1565                 sprintf 'Added file %s had mode changed by Configure to %03o',
1566                     $file, $mode;
1567         }
1568         if ($size != 0) {
1569             push @errors,
1570                 "Added file $file had sized changed by Configure to $size";
1571         }
1572         unlink $file or die "Can't unlink $file: $!";
1573     }
1574     foreach my $dir (@created_dirs) {
1575         rmdir $dir or die "Can't rmdir $dir: $!";
1576     }
1577     skip("@errors")
1578         if @errors;
1579 }
1580
1581 # Correct makefile for newer GNU gcc
1582 # Only really needed if you comment out the use of blead's makedepend.SH
1583 {
1584     local $^I = "";
1585     local @ARGV = qw(makefile x2p/makefile);
1586     while (<>) {
1587         print unless /<(?:built-in|command|stdin)/;
1588     }
1589 }
1590
1591 if ($major == 2 && extract_from_file('perl.c', qr/^     fclose\(e_fp\);$/)) {
1592     # need to patch perl.c to avoid calling fclose() twice on e_fp when using -e
1593     # This diff is part of commit ab821d7fdc14a438. The second close was
1594     # introduced with perl-5.002, commit a5f75d667838e8e7
1595     # Might want a6c477ed8d4864e6 too, for the corresponding change to pp_ctl.c
1596     # (likely without this, eval will have "fun")
1597     apply_patch(<<'EOPATCH');
1598 diff --git a/perl.c b/perl.c
1599 index 03c4d48..3c814a2 100644
1600 --- a/perl.c
1601 +++ b/perl.c
1602 @@ -252,6 +252,7 @@ setuid perl scripts securely.\n");
1603  #ifndef VMS  /* VMS doesn't have environ array */
1604      origenviron = environ;
1605  #endif
1606 +    e_tmpname = Nullch;
1607  
1608      if (do_undump) {
1609  
1610 @@ -405,6 +406,7 @@ setuid perl scripts securely.\n");
1611      if (e_fp) {
1612         if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
1613             croak("Can't write to temp file for -e: %s", Strerror(errno));
1614 +       e_fp = Nullfp;
1615         argc++,argv--;
1616         scriptname = e_tmpname;
1617      }
1618 @@ -470,10 +472,10 @@ setuid perl scripts securely.\n");
1619      curcop->cop_line = 0;
1620      curstash = defstash;
1621      preprocess = FALSE;
1622 -    if (e_fp) {
1623 -       fclose(e_fp);
1624 -       e_fp = Nullfp;
1625 +    if (e_tmpname) {
1626         (void)UNLINK(e_tmpname);
1627 +       Safefree(e_tmpname);
1628 +       e_tmpname = Nullch;
1629      }
1630  
1631      /* now that script is parsed, we can modify record separator */
1632 @@ -1369,7 +1371,7 @@ SV *sv;
1633         scriptname = xfound;
1634      }
1635  
1636 -    origfilename = savepv(e_fp ? "-e" : scriptname);
1637 +    origfilename = savepv(e_tmpname ? "-e" : scriptname);
1638      curcop->cop_filegv = gv_fetchfile(origfilename);
1639      if (strEQ(origfilename,"-"))
1640         scriptname = "";
1641
1642 EOPATCH
1643 }
1644
1645 if ($major < 8 && $^O eq 'openbsd'
1646     && !extract_from_file('perl.h', qr/include <unistd\.h>/)) {
1647     # This is part of commit 3f270f98f9305540, applied at a slightly different
1648     # location in perl.h, where the context is stable back to 5.000
1649     apply_patch(<<'EOPATCH');
1650 diff --git a/perl.h b/perl.h
1651 index 9418b52..b8b1a7c 100644
1652 --- a/perl.h
1653 +++ b/perl.h
1654 @@ -496,6 +496,10 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
1655  #   include <sys/param.h>
1656  #endif
1657  
1658 +/* If this causes problems, set i_unistd=undef in the hint file.  */
1659 +#ifdef I_UNISTD
1660 +#   include <unistd.h>
1661 +#endif
1662  
1663  /* Use all the "standard" definitions? */
1664  #if defined(STANDARD_C) && defined(I_STDLIB)
1665 EOPATCH
1666 }
1667
1668 if ($major == 4 && extract_from_file('scope.c', qr/\(SV\*\)SSPOPINT/)) {
1669     # [PATCH] 5.004_04 +MAINT_TRIAL_1 broken when sizeof(int) != sizeof(void)
1670     # Fixes a bug introduced in 161b7d1635bc830b
1671     system 'git show 9002cb76ec83ef7f | patch -p1'
1672         and die;
1673 }
1674
1675 if ($major == 4 && extract_from_file('av.c', qr/AvARRAY\(av\) = 0;/)) {
1676     # Fixes a bug introduced in 1393e20655efb4bc
1677     system 'git show e1c148c28bf3335b av.c | patch -p1'
1678         and die;
1679 }
1680
1681 if ($major == 4 && $^O eq 'linux') {
1682     # Whilst this is fixed properly in f0784f6a4c3e45e1 which provides the
1683     # Configure probe, it's easier to back out the problematic changes made in
1684     # these previous commits:
1685     if (extract_from_file('doio.c',
1686                           qr!^/\* XXX REALLY need metaconfig test \*/$!)) {
1687         system 'git show -R 4682965a1447ea44 doio.c | patch -p1'
1688             and die;
1689     }
1690     if (my $token = extract_from_file('doio.c',
1691                                       qr!^#if (defined\(__sun(?:__)?\)) && defined\(__svr4__\) /\* XXX Need metaconfig test \*/$!)) {
1692         my $patch = `git show -R 9b599b2a63d2324d doio.c`;
1693         $patch =~ s/defined\(__sun__\)/$token/g;
1694         apply_patch($patch);
1695     }
1696     if (extract_from_file('doio.c',
1697                           qr!^/\* linux \(and Solaris2\?\) uses :$!)) {
1698         system 'git show -R 8490252049bf42d3 doio.c | patch -p1'
1699             and die;
1700     }
1701     if (extract_from_file('doio.c',
1702                           qr/^      unsemds.buf = &semds;$/)) {
1703         system 'git show -R 8e591e46b4c6543e | patch -p1'
1704             and die;
1705     }
1706     if (extract_from_file('doio.c',
1707                           qr!^#ifdef __linux__  /\* XXX Need metaconfig test \*/$!)) {
1708         # Part of commit 3e3baf6d63945cb6
1709         apply_patch(<<'EOPATCH');
1710 diff --git b/doio.c a/doio.c
1711 index 62b7de9..0d57425 100644
1712 --- b/doio.c
1713 +++ a/doio.c
1714 @@ -1333,9 +1331,6 @@ SV **sp;
1715      char *a;
1716      I32 id, n, cmd, infosize, getinfo;
1717      I32 ret = -1;
1718 -#ifdef __linux__       /* XXX Need metaconfig test */
1719 -    union semun unsemds;
1720 -#endif
1721  
1722      id = SvIVx(*++mark);
1723      n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
1724 @@ -1364,29 +1359,11 @@ SV **sp;
1725             infosize = sizeof(struct semid_ds);
1726         else if (cmd == GETALL || cmd == SETALL)
1727         {
1728 -#ifdef __linux__       /* XXX Need metaconfig test */
1729 -/* linux uses :
1730 -   int semctl (int semid, int semnun, int cmd, union semun arg)
1731 -
1732 -       union semun {
1733 -            int val;
1734 -            struct semid_ds *buf;
1735 -            ushort *array;
1736 -       };
1737 -*/
1738 -            union semun semds;
1739 -           if (semctl(id, 0, IPC_STAT, semds) == -1)
1740 -#else
1741             struct semid_ds semds;
1742             if (semctl(id, 0, IPC_STAT, &semds) == -1)
1743 -#endif
1744                 return -1;
1745             getinfo = (cmd == GETALL);
1746 -#ifdef __linux__       /* XXX Need metaconfig test */
1747 -           infosize = semds.buf->sem_nsems * sizeof(short);
1748 -#else
1749             infosize = semds.sem_nsems * sizeof(short);
1750 -#endif
1751                 /* "short" is technically wrong but much more portable
1752                    than guessing about u_?short(_t)? */
1753         }
1754 @@ -1429,12 +1406,7 @@ SV **sp;
1755  #endif
1756  #ifdef HAS_SEM
1757      case OP_SEMCTL:
1758 -#ifdef __linux__       /* XXX Need metaconfig test */
1759 -        unsemds.buf = (struct semid_ds *)a;
1760 -       ret = semctl(id, n, cmd, unsemds);
1761 -#else
1762         ret = semctl(id, n, cmd, (struct semid_ds *)a);
1763 -#endif
1764         break;
1765  #endif
1766  #ifdef HAS_SHM
1767 EOPATCH
1768     }
1769     # Incorrect prototype added as part of 8ac853655d9b7447, fixed as part of
1770     # commit dc45a647708b6c54, with at least one intermediate modification.
1771     # Correct prototype for gethostbyaddr has socklen_t second. Linux has
1772     # uint32_t first for getnetbyaddr.
1773     # Easiest just to remove, instead of attempting more complex patching.
1774     # Something similar may be needed on other platforms.
1775     edit_file('pp_sys.c', sub {
1776                   my $code = shift;
1777                   $code =~ s/^    struct hostent \*(?:PerlSock_)?gethostbyaddr\([^)]+\);$//m;
1778                   $code =~ s/^    struct netent \*getnetbyaddr\([^)]+\);$//m;
1779                   return $code;
1780               });
1781 }
1782
1783 if ($major < 10 and -f 'ext/IPC/SysV/SysV.xs') {
1784     edit_file('ext/IPC/SysV/SysV.xs', sub {
1785                   my $xs = shift;
1786                   my $fixed = <<'EOFIX';
1787
1788 #include <sys/types.h>
1789 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
1790 #ifndef HAS_SEM
1791 #   include <sys/ipc.h>
1792 #endif
1793 #   ifdef HAS_MSG
1794 #       include <sys/msg.h>
1795 #   endif
1796 #   ifdef HAS_SHM
1797 #       if defined(PERL_SCO) || defined(PERL_ISC)
1798 #           include <sys/sysmacros.h>   /* SHMLBA */
1799 #       endif
1800 #      include <sys/shm.h>
1801 #      ifndef HAS_SHMAT_PROTOTYPE
1802            extern Shmat_t shmat (int, char *, int);
1803 #      endif
1804 #      if defined(HAS_SYSCONF) && defined(_SC_PAGESIZE)
1805 #          undef  SHMLBA /* not static: determined at boot time */
1806 #          define SHMLBA sysconf(_SC_PAGESIZE)
1807 #      elif defined(HAS_GETPAGESIZE)
1808 #          undef  SHMLBA /* not static: determined at boot time */
1809 #          define SHMLBA getpagesize()
1810 #      endif
1811 #   endif
1812 #endif
1813 EOFIX
1814                   $xs =~ s!
1815 #include <sys/types\.h>
1816 .*
1817 (#ifdef newCONSTSUB|/\* Required)!$fixed$1!ms;
1818                   return $xs;
1819               });
1820 }
1821
1822 if (-f 'ext/POSIX/Makefile.PL'
1823     && extract_from_file('ext/POSIX/Makefile.PL',
1824                          qr/Explicitly avoid including/)) {
1825     # commit 6695a346c41138df, which effectively reverts 170888cff5e2ffb7
1826
1827     # PERL5LIB is populated by make_ext.pl with paths to the modules we need
1828     # to run, don't override this with "../../lib" since that may not have
1829     # been populated yet in a parallel build.
1830     apply_patch(<<'EOPATCH');
1831 diff --git a/ext/POSIX/Makefile.PL b/ext/POSIX/Makefile.PL
1832 index 392b6fb..9e6d091 100644
1833 --- a/ext/POSIX/Makefile.PL
1834 +++ b/ext/POSIX/Makefile.PL
1835 @@ -1,7 +1,3 @@
1836 -# Explicitly avoid including '.' in @INC; autoloader gets confused since it
1837 -# can find POSIX.pm, but can't find autosplit.ix.
1838 -BEGIN { @INC = '../../lib';}
1839 -#
1840  use ExtUtils::MakeMaker;
1841  use ExtUtils::Constant 0.11 'WriteConstants';
1842  use Config;
1843 EOPATCH
1844 }
1845
1846 # Parallel build for miniperl is safe
1847 system "make $j miniperl </dev/null";
1848
1849 my $expected = $target =~ /^test/ ? 't/perl'
1850     : $target eq 'Fcntl' ? "lib/auto/Fcntl/Fcntl.$Config{so}"
1851     : $target;
1852 my $real_target = $target eq 'Fcntl' ? $expected : $target;
1853
1854 if ($target ne 'miniperl') {
1855     # Nearly all parallel build issues fixed by 5.10.0. Untrustworthy before that.
1856     $j = '' if $major < 10;
1857
1858     if ($real_target eq 'test_prep') {
1859         if ($major < 8) {
1860             # test-prep was added in 5.004_01, 3e3baf6d63945cb6.
1861             # renamed to test_prep in 2001 in 5fe84fd29acaf55c.
1862             # earlier than that, just make test. It will be fast enough.
1863             $real_target = extract_from_file('Makefile.SH',
1864                                              qr/^(test[-_]prep):/,
1865                                              'test');
1866         }
1867     }
1868
1869     system "make $j $real_target </dev/null";
1870 }
1871
1872 my $missing_target = $expected =~ /perl$/ ? !-x $expected : !-r $expected;
1873
1874 if ($options{'test-build'}) {
1875     report_and_exit($missing_target, 'could build', 'could not build',
1876                     $real_target);
1877 } elsif ($missing_target) {
1878     skip("could not build $real_target");
1879 }
1880
1881 match_and_exit($real_target) if $match;
1882
1883 if (defined $options{'one-liner'}) {
1884     my $exe = $target =~ /^(?:perl$|test)/ ? 'perl' : 'miniperl';
1885     unshift @ARGV, "./$exe", '-Ilib', '-e', $options{'one-liner'};
1886 }
1887
1888 # This is what we came here to run:
1889
1890 if (exists $Config{ldlibpthname}) {
1891     require Cwd;
1892     my $varname = $Config{ldlibpthname};
1893     my $cwd = Cwd::getcwd();
1894     if (defined $ENV{$varname}) {
1895         $ENV{$varname} = $cwd . $Config{path_sep} . $ENV{$varname};
1896     } else {
1897         $ENV{$varname} = $cwd;
1898     }
1899 }
1900
1901 my $ret = system @ARGV;
1902
1903 report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
1904
1905 # Local variables:
1906 # cperl-indent-level: 4
1907 # indent-tabs-mode: nil
1908 # End:
1909 #
1910 # ex: set ts=8 sts=4 sw=4 et: