This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
bisect-runner.pl will now invoke with ./perl -Ilib if it sees a #!./perl line
[perl5.git] / Porting / bisect-runner.pl
CommitLineData
6a8dbfd7
NC
1#!/usr/bin/perl -w
2use strict;
3
390a69a9 4use Getopt::Long qw(:config bundling no_auto_abbrev);
77ae6092 5use Pod::Usage;
2526f4b8 6use Config;
6a8dbfd7 7
2526f4b8
NC
8my @targets
9 = qw(config.sh config.h miniperl lib/Config.pm Fcntl perl test_prep);
6a8dbfd7 10
f4800c99
NC
11my %options =
12 (
f4800c99
NC
13 'expect-pass' => 1,
14 clean => 1, # mostly for debugging this
15 );
6a8dbfd7 16
e3caab27
NC
17# We accept #!./miniperl and #!./perl
18# We don't accept #!miniperl and #!perl as their intent is ambiguous
19my $run_with_our_perl = qr{\A#!(\./(?:mini)?perl)\b};
20
fdbac266
NC
21my $linux64 = `uname -sm` eq "Linux x86_64\n" ? '64' : '';
22
599ee4f7
NC
23my @paths;
24
25if ($^O eq 'linux') {
26 # This is the search logic for a multi-arch library layout
27 # added to linux.sh in commits 40f026236b9959b7 and dcffd848632af2c7.
28 my $gcc = -x '/usr/bin/gcc' ? '/usr/bin/gcc' : 'gcc';
29
30 foreach (`$gcc -print-search-dirs`) {
31 next unless /^libraries: =(.*)/;
32 foreach (split ':', $1) {
33 next if m/gcc/;
34 next unless -d $_;
35 s!/$!!;
36 push @paths, $_;
37 }
38 }
39}
40
41push @paths, map {$_ . $linux64} qw(/usr/local/lib /lib /usr/lib);
390a69a9
NC
42
43my %defines =
44 (
45 usedevel => '',
46 optimize => '-g',
9913adee 47 ld => 'cc',
fdbac266 48 ($linux64 ? (libpth => \@paths) : ()),
390a69a9
NC
49 );
50
f4800c99 51unless(GetOptions(\%options,
32ffe018 52 'target=s', 'make=s', 'jobs|j=i', 'expect-pass=i',
f4800c99 53 'expect-fail' => sub { $options{'expect-pass'} = 0; },
529d2ac2 54 'clean!', 'one-liner|e=s', 'c', 'l', 'w', 'match=s',
66b521dd
NC
55 'no-match=s' => sub {
56 $options{match} = $_[1];
57 $options{'expect-pass'} = 0;
58 },
59 'force-manifest', 'force-regen', 'test-build', 'validate',
df14fc13 60 'all-fixups', 'early-fixup=s@', 'late-fixup=s@',
66b521dd 61 'check-args', 'check-shebang!', 'usage|help|?', 'A=s@',
390a69a9
NC
62 'D=s@' => sub {
63 my (undef, $val) = @_;
64 if ($val =~ /\A([^=]+)=(.*)/s) {
65 $defines{$1} = length $2 ? $2 : "\0";
66 } else {
67 $defines{$val} = '';
68 }
69 },
70 'U=s@' => sub {
71 $defines{$_[1]} = undef;
72 },
6a8dbfd7 73 )) {
77ae6092 74 pod2usage(exitval => 255, verbose => 1);
6a8dbfd7
NC
75}
76
0bc550ba 77my ($target, $match) = @options{qw(target match)};
e295b7be 78
b826a648
NC
79@ARGV = ('sh', '-c', 'cd t && ./perl TEST base/*.t')
80 if $options{validate} && !@ARGV;
81
8fc3c209 82pod2usage(exitval => 0, verbose => 2) if $options{usage};
77ae6092
NC
83pod2usage(exitval => 255, verbose => 1)
84 unless @ARGV || $match || $options{'test-build'} || defined $options{'one-liner'};
fc4401c6
NC
85pod2usage(exitval => 255, verbose => 1)
86 if !$options{'one-liner'} && ($options{l} || $options{w});
6a8dbfd7 87
bf8fb529
NC
88check_shebang($ARGV[0])
89 if $options{'check-shebang'} && @ARGV && !$options{match};
7cffc32d 90
f4800c99 91exit 0 if $options{'check-args'};
6a8dbfd7 92
77ae6092
NC
93=head1 NAME
94
95bisect.pl - use git bisect to pinpoint changes
96
97=head1 SYNOPSIS
98
99 # When did this become an error?
100 .../Porting/bisect.pl -e 'my $a := 2;'
71d80638 101 # When did this stop being an error?
77ae6092 102 .../Porting/bisect.pl --expect-fail -e '1 // 2'
80be57dd 103 # When were all lines matching this pattern removed from all files?
77ae6092 104 .../Porting/bisect.pl --match '\b(?:PL_)hash_seed_set\b'
80be57dd 105 # When was some line matching this pattern added to some file?
77ae6092 106 .../Porting/bisect.pl --expect-fail --match '\buseithreads\b'
80be57dd 107 # When did this test program stop exiting 0?
d398528a 108 .../Porting/bisect.pl -- ./perl -Ilib ../test_prog.pl
f7f0fdee
JL
109 # When did this test start failing?
110 .../Porting/bisect.pl -- ./perl -Ilib t/TEST op/sort.t
77ae6092
NC
111 # When did this first become valid syntax?
112 .../Porting/bisect.pl --target=miniperl --end=v5.10.0 \
113 --expect-fail -e 'my $a := 2;'
114 # What was the last revision to build with these options?
115 .../Porting/bisect.pl --test-build -Dd_dosuid
116
117=head1 DESCRIPTION
118
facd1b88 119Together F<bisect.pl> and F<bisect-runner.pl> attempt to automate the use
77ae6092
NC
120of C<git bisect> as much as possible. With one command (and no other files)
121it's easy to find out
122
123=over 4
124
125=item *
126
127Which commit caused this example code to break?
128
129=item *
130
131Which commit caused this example code to start working?
132
133=item *
134
a9b1bbfe 135Which commit added the first file to match this regex?
77ae6092
NC
136
137=item *
138
a9b1bbfe 139Which commit removed the last file to match this regex?
77ae6092
NC
140
141=back
142
143usually without needing to know which versions of perl to use as start and
144end revisions.
145
facd1b88 146By default F<bisect.pl> will process all options, then use the rest of the
77ae6092
NC
147command line as arguments to list C<system> to run a test case. By default,
148the test case should pass (exit with 0) on earlier perls, and fail (exit
f7f0fdee
JL
149non-zero) on I<blead> (note that running most of perl's test files directly
150won't do this, you'll need to run them through a harness to get the proper
151error code). F<bisect.pl> will use F<bisect-runner.pl> to find the earliest
152stable perl version on which the test case passes, check that it fails on
153blead, and then use F<bisect-runner.pl> with C<git bisect run> to find the
154commit which caused the failure.
77ae6092
NC
155
156Because the test case is the complete argument to C<system>, it is easy to
157run something other than the F<perl> built, if necessary. If you need to run
e3caab27
NC
158the perl built, you'll probably need to invoke it as C<./perl -Ilib ...>.
159As a special case, if the first argument of the test case is a readable file
160(whether executable or not), matching C<qr{\A#!./(?:mini)?perl\b}> then it
161will have C<./perl> <-Ilib> (or C<./miniperl>) prepended to it.
77ae6092 162
5842706e
NC
163You need a clean checkout to run a bisect, and you can't use the checkout
164which contains F<Porting/bisect.pl> (because C<git bisect>) will check out
165a revision before F<Porting/bisect-runner.pl> was added, which
166C<git bisect run> needs). If your working checkout is called F<perl>, the
167simplest solution is to make a local clone, and run from that. I<i.e.>:
168
169 cd ..
170 git clone perl perl2
171 cd perl2
172 ../perl/Porting/bisect.pl ...
173
facd1b88 174By default, F<bisect-runner.pl> will automatically disable the build of
cfadff5f
NC
175L<DB_File> for commits earlier than ccb44e3bf3be2c30, as it's not practical
176to patch DB_File 1.70 and earlier to build with current Berkeley DB headers.
177(ccb44e3bf3be2c30 was in September 1999, between 5.005_62 and 5.005_63.)
178If your F<db.h> is old enough you can override this with C<-Unoextensions>.
179
77ae6092
NC
180=head1 OPTIONS
181
182=over 4
183
184=item *
185
186--start I<commit-ish>
187
188Earliest revision to test, as a I<commit-ish> (a tag, commit or anything
facd1b88 189else C<git> understands as a revision). If not specified, F<bisect.pl> will
3ffe2687
NC
190search stable perl releases until it finds one where the test case passes.
191The default is to search from 5.002 to 5.14.0. If F<bisect.pl> detects that
192the checkout is on a case insensitive file system, it will search from
1935.005 to 5.14.0
77ae6092
NC
194
195=item *
196
197--end I<commit-ish>
198
199Most recent revision to test, as a I<commit-ish>. If not specified, defaults
b4f0ec5f 200to I<blead>.
77ae6092
NC
201
202=item *
203
204--target I<target>
205
206F<Makefile> target (or equivalent) needed, to run the test case. If specified,
207this should be one of
208
209=over 4
210
211=item *
212
213I<config.sh>
214
facd1b88 215Just run F<./Configure>
77ae6092
NC
216
217=item *
218
219I<config.h>
220
221Run the various F<*.SH> files to generate F<Makefile>, F<config.h>, I<etc>.
222
223=item *
224
225I<miniperl>
226
227Build F<miniperl>.
228
229=item *
230
231I<lib/Config.pm>
232
233Use F<miniperl> to build F<lib/Config.pm>
234
235=item *
236
2526f4b8
NC
237I<Fcntl>
238
239Build F<lib/auto/Fcntl/Fnctl.so> (strictly, C<.$Config{so}>). As L<Fcntl>
240is simple XS module present since 5.000, this provides a fast test of
b4f0ec5f 241whether XS modules can be built. Note, XS modules are built by F<miniperl>,
2526f4b8
NC
242hence this target will not build F<perl>.
243
244=item *
245
77ae6092
NC
246I<perl>
247
248Build F<perl>. This also builds pure-Perl modules in F<cpan>, F<dist> and
2526f4b8
NC
249F<ext>. XS modules (such as L<Fcntl>) are not built.
250
251=item *
252
77ae6092
NC
253I<test_prep>
254
255Build everything needed to run the tests. This is the default if we're
256running test code, but is time consuming, as it means building all
b4f0ec5f 257XS modules. For older F<Makefile>s, the previous name of C<test-prep>
77ae6092
NC
258is automatically substituted. For very old F<Makefile>s, C<make test> is
259run, as there is no target provided to just get things ready, and for 5.004
260and earlier the tests run very quickly.
261
262=back
263
264=item *
265
266--one-liner 'code to run'
267
268=item *
269
270-e 'code to run'
271
a1756669 272Example code to run, just like you'd use with C<perl -e>.
77ae6092
NC
273
274This prepends C<./perl -Ilib -e 'code to run'> to the test case given,
facd1b88 275or F<./miniperl> if I<target> is C<miniperl>.
77ae6092
NC
276
277(Usually you'll use C<-e> instead of providing a test case in the
facd1b88 278non-option arguments to F<bisect.pl>)
77ae6092
NC
279
280C<-E> intentionally isn't supported, as it's an error in 5.8.0 and earlier,
281which interferes with detecting errors in the example code itself.
282
283=item *
284
529d2ac2
NC
285-c
286
287Add C<-c> to the command line, to cause perl to exit after syntax checking.
288
289=item *
290
fc4401c6
NC
291-l
292
293Add C<-l> to the command line with C<-e>
294
295This will automatically append a newline to every output line of your testcase.
296Note that you can't specify an argument to F<perl>'s C<-l> with this, as it's
297not feasible to emulate F<perl>'s somewhat quirky switch parsing with
298L<Getopt::Long>. If you need the full flexibility of C<-l>, you need to write
299a full test case, instead of using C<bisect.pl>'s C<-e> shortcut.
300
301=item *
302
303-w
304
305Add C<-w> to the command line with C<-e>
306
529d2ac2
NC
307It's not valid to pass C<-c>, C<-l> or C<-w> to C<bisect.pl> unless you are
308also using C<-e>
fc4401c6
NC
309
310=item *
311
77ae6092
NC
312--expect-fail
313
314The test case should fail for the I<start> revision, and pass for the I<end>
315revision. The bisect run will find the first commit where it passes.
316
317=item *
318
28c4aad0 319-D I<config_arg=value>
77ae6092
NC
320
321=item *
322
28c4aad0 323-U I<config_arg>
77ae6092
NC
324
325=item *
326
28c4aad0 327-A I<config_arg=value>
77ae6092 328
28c4aad0
DM
329Arguments (C<-A>, C<-D>, C<-U>) to pass to F<Configure>. For example,
330
331 -Dnoextensions=Encode
332 -Uusedevel
333 -Accflags=-DNO_MATHOMS
334
335Repeated C<-A> arguments are passed
77ae6092 336through as is. C<-D> and C<-U> are processed in order, and override
af7c500f
NC
337previous settings for the same parameter. F<bisect-runner.pl> emulates
338C<-Dnoextensions> when F<Configure> itself does not provide it, as it's
339often very useful to be able to disable some XS extensions.
77ae6092
NC
340
341=item *
342
32ffe018
NC
343--make I<make-prog>
344
345The C<make> command to use. If this not set, F<make> is used. If this is
346set, it also adds a C<-Dmake=...> else some recursive make invocations
347in extensions may fail. Typically one would use this as C<--make gmake>
348to use F<gmake> in place of the system F<make>.
349
350=item *
351
b4f0ec5f 352--jobs I<jobs>
77ae6092
NC
353
354=item *
355
b4f0ec5f 356-j I<jobs>
77ae6092 357
d3232d34
NC
358Number of C<make> jobs to run in parallel. A value of 0 suppresses
359parallelism. If F</proc/cpuinfo> exists and can be parsed, or F</sbin/sysctl>
360exists and reports C<hw.ncpu>, or F</usr/bin/getconf> exists and reports
361C<_NPROCESSORS_ONLN> defaults to 1 + I<number of CPUs>. On HP-UX with the
362system make defaults to 0, otherwise defaults to 2.
77ae6092
NC
363
364=item *
365
b4f0ec5f 366--match pattern
77ae6092 367
66b521dd
NC
368=item *
369
370--no-match pattern
371
372Instead of running a test program to determine I<pass> or I<fail>,
373C<--match> will pass if the given regex matches, and hence search for the
374commit that removes the last matching file. C<--no-match> inverts the test,
375to search for the first commit that adds files that match.
bf8fb529
NC
376
377The remaining command line arguments are treated as glob patterns for files
378to match against. If none are specified, then they default as follows:
379
380=over 4
381
382=item *
77ae6092
NC
383
384If no I<target> is specified, the match is against all files in the
bf8fb529
NC
385repository (which is fast).
386
387=item *
388
389If a I<target> is specified, that target is built, and the match is against
390only the built files.
391
392=back
393
394Treating the command line arguments as glob patterns should not cause
395problems, as the perl distribution has never shipped or built files with
396names that contain characters which are globbing metacharacters.
397
398Anything which is not a readable file is ignored, instead of generating an
399error. (If you want an error, run C<grep> or C<ack> as a test case). This
400permits one to easily search in a file that changed its name. For example:
401
402 .../Porting/bisect.pl --match 'Pod.*Functions' 'pod/buildtoc*'
77ae6092 403
66b521dd
NC
404C<--no-match ...> is implemented as C<--expect-fail --match ...>
405
77ae6092
NC
406=item *
407
408--test-build
409
410Test that the build completes, without running any test case.
411
412By default, if the build for the desired I<target> fails to complete,
413F<bisect-runner.pl> reports a I<skip> back to C<git bisect>, the assumption
414being that one wants to find a commit which changed state "builds && passes"
415to "builds && fails". If instead one is interested in which commit broke the
416build (possibly for particular F<Configure> options), use I<--test-build>
417to treat a build failure as a failure, not a "skip".
418
b4f0ec5f
NC
419Often this option isn't as useful as it first seems, because I<any> build
420failure will be reported to C<git bisect> as a failure, not just the failure
421that you're interested in. Generally, to debug a particular problem, it's
422more useful to use a I<target> that builds properly at the point of interest,
423and then a test case that runs C<make>. For example:
424
425 .../Porting/bisect.pl --start=perl-5.000 --end=perl-5.002 \
426 --expect-fail --force-manifest --target=miniperl make perl
427
facd1b88
NC
428will find the first revision capable of building L<DynaLoader> and then
429F<perl>, without becoming confused by revisions where F<miniperl> won't
b4f0ec5f
NC
430even link.
431
77ae6092
NC
432=item *
433
b4f0ec5f
NC
434--force-manifest
435
77ae6092
NC
436By default, a build will "skip" if any files listed in F<MANIFEST> are not
437present. Usually this is useful, as it avoids false-failures. However, there
438are some long ranges of commits where listed files are missing, which can
439cause a bisect to abort because all that remain are skipped revisions.
440
441In these cases, particularly if the test case uses F<miniperl> and no modules,
442it may be more useful to force the build to continue, even if files
443F<MANIFEST> are missing.
444
445=item *
446
bfa52998
NC
447--force-regen
448
449Run C<make regen_headers> before building F<miniperl>. This may fix a build
450that otherwise would skip because the generated headers at that revision
451are stale. It's not the default because it conceals this error in the true
452state of such revisions.
453
454=item *
455
77ae6092
NC
456--expect-pass [0|1]
457
458C<--expect-pass=0> is equivalent to C<--expect-fail>. I<1> is the default.
459
460=item *
461
86905c1e
NC
462--all-fixups
463
464F<bisect-runner.pl> will minimally patch various files on a platform and
465version dependent basis to get the build to complete. Normally it defers
466doing this as long as possible - C<.SH> files aren't patched until after
467F<Configure> is run, and C<C> and C<XS> code isn't patched until after
468F<miniperl> is built. If C<--all-fixups> is specified, all the fixups are
469done before running C<Configure>. In rare cases adding this may cause a
470bisect to abort, because an inapplicable patch or other fixup is attempted
471for a revision which would usually have already I<skip>ed. If this happens,
472please report it as a bug, giving the OS and problem revision.
473
474=item *
475
df14fc13
NC
476--early-fixup file
477
478=item *
479
480--late-fixup file
481
482Specify a file containing a patch or other fixup for the source code. The
483action to take depends on the first line of the fixup file
484
485=over 4
486
487=item *
488
489C<#!perl>
490
491If the first line starts C<#!perl> then the file is run using C<$^X>
492
493=item *
494
495C<#!/absolute/path>
496
497If a shebang line is present the file is executed using C<system>
498
499=item *
500
501C<I<filename> =~ /I<pattern>/>
502
503=item *
504
505C<I<filename> !~ /I<pattern>/>
506
507If I<filename> does not exist then the fixup file's contents are ignored.
508Otherwise, for C<=~>, if it contains a line matching I<pattern>, then the
509file is fed to C<patch -p1> on standard input. For C<=~>, the patch is
510applied if no lines match the pattern.
511
512As the empty pattern in Perl is a special case (it matches the most recent
513sucessful match) which is not useful here, an the treatment of empty pattern
514is special-cased. C<I<filename> =~ //> applies the patch if filename is
515present. C<I<filename> !~ //> applies the patch if filename missing. This
516makes it easy to unconditionally apply patches to files, and to use a patch
517as a way of creating a new file.
518
519=item *
520
521Otherwise, the file is assumed to be a patch, and always applied.
522
523=back
524
525I<early-fixup>s are applied before F<./Configure> is run. I<late-fixup>s are
526applied just after F<./Configure> is run.
527
528These options can be specified more than once. I<file> is actually expanded
529as a glob pattern. Globs that do not match are errors, as are missing files.
530
531=item *
532
77ae6092
NC
533--no-clean
534
535Tell F<bisect-runner.pl> not to clean up after the build. This allows one
536to use F<bisect-runner.pl> to build the current particular perl revision for
537interactive testing, or for debugging F<bisect-runner.pl>.
538
539Passing this to F<bisect.pl> will likely cause the bisect to fail badly.
540
541=item *
542
195ed8b1
NC
543--validate
544
3f14869b 545Test that all stable revisions can be built. By default, attempts to build
3ffe2687
NC
546I<blead>, I<v5.14.0> .. I<perl-5.002> (or I<perl5.005> on a case insensitive
547file system). Stops at the first failure, without
3f14869b
NC
548cleaning the checkout. Use I<--start> to specify the earliest revision to
549test, I<--end> to specify the most recent. Useful for validating a new
195ed8b1
NC
550OS/CPU/compiler combination. For example
551
fc4401c6 552 ../perl/Porting/bisect.pl --validate -le 'print "Hello from $]"'
195ed8b1 553
e2760528
NC
554If no testcase is specified, the default is to use F<t/TEST> to run
555F<t/base/*.t>
556
195ed8b1
NC
557=item *
558
77ae6092
NC
559--check-args
560
561Validate the options and arguments, and exit silently if they are valid.
562
563=item *
564
7cffc32d
NC
565--check-shebang
566
567Validate that the test case isn't an executable file with a
568C<#!/usr/bin/perl> line (or similar). As F<bisect-runner.pl> does B<not>
e3caab27
NC
569automatically prepend C<./perl> to the test case, a I<#!> line specifying an
570external F<perl> binary will cause the test case to always run with I<that>
571F<perl>, not the F<perl> built by the bisect runner. Likely this is not what
572you wanted. If your test case is actually a wrapper script to run other
7cffc32d
NC
573commands, you should run it with an explicit interpreter, to be clear. For
574example, instead of C<../perl/Porting/bisect.pl ~/test/testcase.pl> you'd
575run C<../perl/Porting/bisect.pl /usr/bin/perl ~/test/testcase.pl>
576
577=item *
578
77ae6092
NC
579--usage
580
581=item *
582
583--help
584
585=item *
586
587-?
588
589Display the usage information and exit.
590
591=back
592
593=cut
594
f6647108
NC
595# Ensure we always exit with 255, to cause git bisect to abort.
596sub croak_255 {
597 my $message = join '', @_;
598 if ($message =~ /\n\z/) {
599 print STDERR $message;
600 } else {
601 my (undef, $file, $line) = caller 1;
602 print STDERR "@_ at $file line $line\n";
603 }
604 exit 255;
605}
606
607sub die_255 {
608 croak_255(@_);
609}
610
611die_255("$0: Can't build $target")
612 if defined $target && !grep {@targets} $target;
6a8dbfd7 613
df14fc13
NC
614foreach my $phase (qw(early late)) {
615 next unless $options{"$phase-fixup"};
616 my $bail_out;
617 require File::Glob;
618 my @expanded;
619 foreach my $glob (@{$options{"$phase-fixup"}}) {
620 my @got = File::Glob::bsd_glob($glob);
621 push @expanded, @got ? @got : $glob;
622 }
623 @expanded = sort @expanded;
624 $options{"$phase-fixup"} = \@expanded;
625 foreach (@expanded) {
626 unless (-f $_) {
627 print STDERR "$phase-fixup '$_' is not a readable file\n";
628 ++$bail_out;
629 }
630 }
631 exit 255 if $bail_out;
632}
633
8f13c642
NC
634unless (exists $defines{cc}) {
635 # If it fails, the heuristic of 63f9ec3008baf7d6 is noisy, and hence
c34d8429 636 # confusing.
8f13c642
NC
637 # FIXME - really it should be replaced with a proper test of
638 # "can we build something?" and a helpful diagnostic if we can't.
639 # For now, simply move it here.
c34d8429 640 $defines{cc} = (`ccache -V`, $?) ? 'cc' : 'ccache cc';
8f13c642
NC
641}
642
0bc550ba 643my $j = $options{jobs} ? "-j$options{jobs}" : '';
6a8dbfd7 644
32ffe018
NC
645if (exists $options{make}) {
646 if (!exists $defines{make}) {
647 $defines{make} = $options{make};
648 }
649} else {
650 $options{make} = 'make';
651}
652
0142f0ce
NC
653# Sadly, however hard we try, I don't think that it will be possible to build
654# modules in ext/ on x86_64 Linux before commit e1666bf5602ae794 on 1999/12/29,
655# which updated to MakeMaker 3.7, which changed from using a hard coded ld
656# in the Makefile to $(LD). On x86_64 Linux the "linker" is gcc.
657
69bf9aba
NC
658sub open_or_die {
659 my $file = shift;
660 my $mode = @_ ? shift : '<';
f6647108 661 open my $fh, $mode, $file or croak_255("Can't open $file: $!");
69bf9aba
NC
662 ${*$fh{SCALAR}} = $file;
663 return $fh;
664}
665
666sub close_or_die {
667 my $fh = shift;
668 return if close $fh;
f6647108
NC
669 croak_255("Can't close: $!") unless ref $fh eq 'GLOB';
670 croak_255("Can't close ${*$fh{SCALAR}}: $!");
69bf9aba
NC
671}
672
d953d40d
NC
673sub system_or_die {
674 my $command = '</dev/null ' . shift;
f6647108 675 system($command) and croak_255("'$command' failed, \$!=$!, \$?=$?");
d953d40d
NC
676}
677
6a8dbfd7
NC
678sub extract_from_file {
679 my ($file, $rx, $default) = @_;
69bf9aba 680 my $fh = open_or_die($file);
6a8dbfd7
NC
681 while (<$fh>) {
682 my @got = $_ =~ $rx;
683 return wantarray ? @got : $got[0]
684 if @got;
685 }
686 return $default if defined $default;
687 return;
688}
689
c59e8fd6
NC
690sub edit_file {
691 my ($file, $munger) = @_;
692 local $/;
69bf9aba 693 my $fh = open_or_die($file);
c59e8fd6 694 my $orig = <$fh>;
f6647108 695 die_255("Can't read $file: $!") unless defined $orig && close $fh;
c59e8fd6
NC
696 my $new = $munger->($orig);
697 return if $new eq $orig;
69bf9aba 698 $fh = open_or_die($file, '>');
f6647108 699 print $fh $new or die_255("Can't print to $file: $!");
69bf9aba 700 close_or_die($fh);
c59e8fd6
NC
701}
702
6fe55cbd
NC
703# AIX supplies a pre-historic patch program, which certainly predates Linux
704# and is probably older than NT. It can't cope with unified diffs. Meanwhile,
705# it's hard enough to get git diff to output context diffs, let alone git show,
706# and nearly all the patches embedded here are unified. So it seems that the
707# path of least resistance is to convert unified diffs to context diffs:
708
709sub process_hunk {
710 my ($from_out, $to_out, $has_from, $has_to, $delete, $add) = @_;
711 ++$$has_from if $delete;
712 ++$$has_to if $add;
713
714 if ($delete && $add) {
715 $$from_out .= "! $_\n" foreach @$delete;
716 $$to_out .= "! $_\n" foreach @$add;
717 } elsif ($delete) {
718 $$from_out .= "- $_\n" foreach @$delete;
719 } elsif ($add) {
720 $$to_out .= "+ $_\n" foreach @$add;
721 }
722}
723
724# This isn't quite general purpose, as it can't cope with
725# '\ No newline at end of file'
726sub ud2cd {
727 my $diff_in = shift;
728 my $diff_out = '';
729
730 # Stuff before the diff
731 while ($diff_in =~ s/\A(?!\*\*\* )(?!--- )([^\n]*\n?)//ms && length $1) {
732 $diff_out .= $1;
733 }
734
735 if (!length $diff_in) {
f6647108 736 die_255("That didn't seem to be a diff");
6fe55cbd
NC
737 }
738
739 if ($diff_in =~ /\A\*\*\* /ms) {
740 warn "Seems to be a context diff already\n";
741 return $diff_out . $diff_in;
742 }
743
744 # Loop for files
745 FILE: while (1) {
746 if ($diff_in =~ s/\A((?:diff |index )[^\n]+\n)//ms) {
747 $diff_out .= $1;
748 next;
749 }
750 if ($diff_in !~ /\A--- /ms) {
751 # Stuff after the diff;
752 return $diff_out . $diff_in;
753 }
754 $diff_in =~ s/\A([^\n]+\n?)//ms;
755 my $line = $1;
f6647108 756 die_255("Can't parse '$line'") unless $line =~ s/\A--- /*** /ms;
6fe55cbd
NC
757 $diff_out .= $line;
758 $diff_in =~ s/\A([^\n]+\n?)//ms;
759 $line = $1;
f6647108 760 die_255("Can't parse '$line'") unless $line =~ s/\A\+\+\+ /--- /ms;
6fe55cbd
NC
761 $diff_out .= $line;
762
763 # Loop for hunks
764 while (1) {
765 next FILE
766 unless $diff_in =~ s/\A\@\@ (-([0-9]+),([0-9]+) \+([0-9]+),([0-9]+)) \@\@[^\n]*\n?//;
767 my ($hunk, $from_start, $from_count, $to_start, $to_count)
768 = ($1, $2, $3, $4, $5);
769 my $from_end = $from_start + $from_count - 1;
770 my $to_end = $to_start + $to_count - 1;
771 my ($from_out, $to_out, $has_from, $has_to, $add, $delete);
772 while (length $diff_in && ($from_count || $to_count)) {
f6647108
NC
773 die_255("Confused in $hunk")
774 unless $diff_in =~ s/\A([^\n]*)\n//ms;
6fe55cbd
NC
775 my $line = $1;
776 $line = ' ' unless length $line;
777 if ($line =~ /^ .*/) {
778 process_hunk(\$from_out, \$to_out, \$has_from, \$has_to,
779 $delete, $add);
780 undef $delete;
781 undef $add;
782 $from_out .= " $line\n";
783 $to_out .= " $line\n";
784 --$from_count;
785 --$to_count;
786 } elsif ($line =~ /^-(.*)/) {
787 push @$delete, $1;
788 --$from_count;
789 } elsif ($line =~ /^\+(.*)/) {
790 push @$add, $1;
791 --$to_count;
792 } else {
f6647108 793 die_255("Can't parse '$line' as part of hunk $hunk");
6fe55cbd
NC
794 }
795 }
796 process_hunk(\$from_out, \$to_out, \$has_from, \$has_to,
797 $delete, $add);
f6647108 798 die_255("No lines in hunk $hunk")
6fe55cbd 799 unless length $from_out || length $to_out;
f6647108 800 die_255("No changes in hunk $hunk")
6fe55cbd
NC
801 unless $has_from || $has_to;
802 $diff_out .= "***************\n";
803 $diff_out .= "*** $from_start,$from_end ****\n";
804 $diff_out .= $from_out if $has_from;
805 $diff_out .= "--- $to_start,$to_end ----\n";
806 $diff_out .= $to_out if $has_to;
807 }
808 }
809}
810
811{
812 my $use_context;
813
814 sub placate_patch_prog {
815 my $patch = shift;
816
817 if (!defined $use_context) {
818 my $version = `patch -v 2>&1`;
f6647108 819 die_255("Can't run `patch -v`, \$?=$?, bailing out")
6fe55cbd
NC
820 unless defined $version;
821 if ($version =~ /Free Software Foundation/) {
822 $use_context = 0;
823 } elsif ($version =~ /Header: patch\.c,v.*\blwall\b/) {
824 # The system patch is older than Linux, and probably older than
825 # Windows NT.
826 $use_context = 1;
ccb58ea9
NC
827 } elsif ($version =~ /Header: patch\.c,v.*\babhinav\b/) {
828 # Thank you HP. No, we have no idea *which* version this is:
829 # $Header: patch.c,v 76.1.1.2.1.3 2001/12/03 12:24:52 abhinav Exp $
830 $use_context = 1;
6fe55cbd
NC
831 } else {
832 # Don't know.
833 $use_context = 0;
834 }
835 }
836
837 return $use_context ? ud2cd($patch) : $patch;
838 }
839}
840
c59e8fd6 841sub apply_patch {
58a28a53
NC
842 my ($patch, $what, $files) = @_;
843 $what = 'patch' unless defined $what;
844 unless (defined $files) {
845 $patch =~ m!^--- a/(\S+)\n\+\+\+ b/\1!sm;
846 $files = " $1";
847 }
6fe55cbd 848 my $patch_to_use = placate_patch_prog($patch);
f6647108 849 open my $fh, '|-', 'patch', '-p1' or die_255("Can't run patch: $!");
6fe55cbd 850 print $fh $patch_to_use;
5fceabf3
NC
851 return if close $fh;
852 print STDERR "Patch is <<'EOPATCH'\n${patch}EOPATCH\n";
56a20cc1
NC
853 print STDERR "\nConverted to a context diff <<'EOCONTEXT'\n${patch_to_use}EOCONTEXT\n"
854 if $patch_to_use ne $patch;
f6647108 855 die_255("Can't $what$files: $?, $!");
c59e8fd6
NC
856}
857
4e540a4e
NC
858sub apply_commit {
859 my ($commit, @files) = @_;
58a28a53
NC
860 my $patch = `git show $commit @files`;
861 if (!defined $patch) {
f6647108
NC
862 die_255("Can't get commit $commit for @files: $?") if @files;
863 die_255("Can't get commit $commit: $?");
58a28a53
NC
864 }
865 apply_patch($patch, "patch $commit", @files ? " for @files" : '');
4e540a4e
NC
866}
867
868sub revert_commit {
869 my ($commit, @files) = @_;
58a28a53
NC
870 my $patch = `git show -R $commit @files`;
871 if (!defined $patch) {
f6647108
NC
872 die_255("Can't get revert commit $commit for @files: $?") if @files;
873 die_255("Can't get revert commit $commit: $?");
58a28a53
NC
874 }
875 apply_patch($patch, "revert $commit", @files ? " for @files" : '');
4e540a4e
NC
876}
877
91ad6f8a
NC
878sub checkout_file {
879 my ($file, $commit) = @_;
880 $commit ||= 'blead';
881 system "git show $commit:$file > $file </dev/null"
f6647108 882 and die_255("Could not extract $file at revision $commit");
91ad6f8a
NC
883}
884
7cffc32d
NC
885sub check_shebang {
886 my $file = shift;
887 return unless -e $file;
e3caab27
NC
888 my $fh = open_or_die($file);
889 my $line = <$fh>;
890 return if $line =~ $run_with_our_perl;
7cffc32d 891 if (!-x $file) {
f6647108 892 die_255("$file is not executable.
7cffc32d
NC
893system($file, ...) is always going to fail.
894
f6647108 895Bailing out");
7cffc32d 896 }
7cffc32d 897 return unless $line =~ m{\A#!(/\S+/perl\S*)\s};
f6647108 898 die_255("$file will always be run by $1
7cffc32d
NC
899It won't be tested by the ./perl we build.
900If you intended to run it with that perl binary, please change your
901test case to
902
903 $1 @ARGV
904
905If you intended to test it with the ./perl we build, please change your
906test case to
907
908 ./perl -Ilib @ARGV
909
910[You may also need to add -- before ./perl to prevent that -Ilib as being
911parsed as an argument to bisect.pl]
912
f6647108 913Bailing out");
7cffc32d
NC
914}
915
ab4a15f9 916sub clean {
f4800c99 917 if ($options{clean}) {
ab4a15f9
NC
918 # Needed, because files that are build products in this checked out
919 # version might be in git in the next desired version.
9da8cb0a 920 system 'git clean -dxf </dev/null';
ab4a15f9
NC
921 # Needed, because at some revisions the build alters checked out files.
922 # (eg pod/perlapi.pod). Also undoes any changes to makedepend.SH
9da8cb0a 923 system 'git reset --hard HEAD </dev/null';
ab4a15f9
NC
924 }
925}
926
927sub skip {
928 my $reason = shift;
929 clean();
930 warn "skipping - $reason";
931 exit 125;
932}
933
f1050811
NC
934sub report_and_exit {
935 my ($ret, $pass, $fail, $desc) = @_;
936
937 clean();
938
f4800c99 939 my $got = ($options{'expect-pass'} ? !$ret : $ret) ? 'good' : 'bad';
f1050811
NC
940 if ($ret) {
941 print "$got - $fail $desc\n";
942 } else {
943 print "$got - $pass $desc\n";
944 }
945
946 exit($got eq 'bad');
947}
948
0afef97d 949sub match_and_exit {
bf8fb529 950 my ($target, @globs) = @_;
0afef97d
NC
951 my $matches = 0;
952 my $re = qr/$match/;
953 my @files;
954
bf8fb529
NC
955 if (@globs) {
956 require File::Glob;
957 foreach (sort map { File::Glob::bsd_glob($_)} @globs) {
958 if (!-f $_ || !-r _) {
959 warn "Skipping matching '$_' as it is not a readable file\n";
960 } else {
961 push @files, $_;
962 }
963 }
964 } else {
0afef97d
NC
965 local $/ = "\0";
966 @files = defined $target ? `git ls-files -o -z`: `git ls-files -z`;
967 chomp @files;
968 }
969
970 foreach my $file (@files) {
69bf9aba 971 my $fh = open_or_die($file);
0afef97d
NC
972 while (<$fh>) {
973 if ($_ =~ $re) {
974 ++$matches;
975 if (tr/\t\r\n -~\200-\377//c) {
976 print "Binary file $file matches\n";
977 } else {
978 $_ .= "\n" unless /\n\z/;
979 print "$file: $_";
980 }
981 }
982 }
69bf9aba 983 close_or_die($fh);
0afef97d
NC
984 }
985 report_and_exit(!$matches,
986 $matches == 1 ? '1 match for' : "$matches matches for",
987 'no matches for', $match);
988}
989
6a8dbfd7 990# Not going to assume that system perl is yet new enough to have autodie
d953d40d 991system_or_die('git clean -dxf');
6a8dbfd7 992
0afef97d 993if (!defined $target) {
bf8fb529 994 match_and_exit(undef, @ARGV) if $match;
0afef97d 995 $target = 'test_prep';
bc96a05a
NC
996}
997
4b081584
NC
998skip('no Configure - is this the //depot/perlext/Compiler branch?')
999 unless -f 'Configure';
1000
1f1c8096
NC
1001my $case_insensitive;
1002{
1003 my ($dev_C, $ino_C) = stat 'Configure';
f6647108 1004 die_255("Could not stat Configure: $!") unless defined $dev_C;
1f1c8096
NC
1005 my ($dev_c, $ino_c) = stat 'configure';
1006 ++$case_insensitive
1007 if defined $dev_c && $dev_C == $dev_c && $ino_C == $ino_c;
1008}
1009
dbcdc176
NC
1010# This changes to PERL_VERSION in 4d8076ea25903dcb in 1999
1011my $major
1012 = extract_from_file('patchlevel.h',
1013 qr/^#define\s+(?:PERL_VERSION|PATCHLEVEL)\s+(\d+)\s/,
1014 0);
1015
750ce942
NC
1016patch_Configure();
1017patch_hints();
86905c1e
NC
1018if ($options{'all-fixups'}) {
1019 patch_SH();
1020 patch_C();
1021 patch_ext();
1022}
df14fc13 1023apply_fixups($options{'early-fixup'});
750ce942 1024
6a8dbfd7
NC
1025# if Encode is not needed for the test, you can speed up the bisect by
1026# excluding it from the runs with -Dnoextensions=Encode
1027# ccache is an easy win. Remove it if it causes problems.
6a8dbfd7
NC
1028# Commit 1cfa4ec74d4933da adds ignore_versioned_solibs to Configure, and sets it
1029# to true in hints/linux.sh
1030# On dromedary, from that point on, Configure (by default) fails to find any
1031# libraries, because it scans /usr/local/lib /lib /usr/lib, which only contain
1032# versioned libraries. Without -lm, the build fails.
1033# Telling /usr/local/lib64 /lib64 /usr/lib64 works from that commit onwards,
1034# until commit faae14e6e968e1c0 adds it to the hints.
1035# However, prior to 1cfa4ec74d4933da telling Configure the truth doesn't work,
1036# because it will spot versioned libraries, pass them to the compiler, and then
1037# bail out pretty early on. Configure won't let us override libswanted, but it
1038# will let us override the entire libs list.
1039
40c94856
NC
1040foreach (@{$options{A}}) {
1041 push @paths, $1 if /^libpth=(.*)/s;
1042}
1043
6a8dbfd7
NC
1044unless (extract_from_file('Configure', 'ignore_versioned_solibs')) {
1045 # Before 1cfa4ec74d4933da, so force the libs list.
1046
1047 my @libs;
1048 # This is the current libswanted list from Configure, less the libs removed
1049 # by current hints/linux.sh
1050 foreach my $lib (qw(sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld
1051 ld sun m crypt sec util c cposix posix ucb BSD)) {
1052 foreach my $dir (@paths) {
40c94856
NC
1053 # Note the wonderful consistency of dot-or-not in the config vars:
1054 next unless -f "$dir/lib$lib.$Config{dlext}"
1055 || -f "$dir/lib$lib$Config{lib_ext}";
6a8dbfd7
NC
1056 push @libs, "-l$lib";
1057 last;
1058 }
1059 }
390a69a9 1060 $defines{libs} = \@libs unless exists $defines{libs};
6a8dbfd7
NC
1061}
1062
390a69a9
NC
1063$defines{usenm} = undef
1064 if $major < 2 && !exists $defines{usenm};
0142f0ce 1065
05ec8abc
NC
1066my ($missing, $created_dirs);
1067($missing, $created_dirs) = force_manifest()
1068 if $options{'force-manifest'};
67382a3b 1069
af7c500f 1070my @ARGS = '-dEs';
390a69a9
NC
1071foreach my $key (sort keys %defines) {
1072 my $val = $defines{$key};
1073 if (ref $val) {
1074 push @ARGS, "-D$key=@$val";
1075 } elsif (!defined $val) {
1076 push @ARGS, "-U$key";
1077 } elsif (!length $val) {
1078 push @ARGS, "-D$key";
1079 } else {
1080 $val = "" if $val eq "\0";
1081 push @ARGS, "-D$key=$val";
1082 }
1083}
1084push @ARGS, map {"-A$_"} @{$options{A}};
1085
6a8dbfd7
NC
1086# </dev/null because it seems that some earlier versions of Configure can
1087# call commands in a way that now has them reading from stdin (and hanging)
1088my $pid = fork;
f6647108 1089die_255("Can't fork: $!") unless defined $pid;
6a8dbfd7 1090if (!$pid) {
7c22f158
NC
1091 open STDIN, '<', '/dev/null';
1092 # If a file in MANIFEST is missing, Configure asks if you want to
1093 # continue (the default being 'n'). With stdin closed or /dev/null,
1094 # it exits immediately and the check for config.sh below will skip.
f6647108 1095 no warnings; # Don't tell me "statement unlikely to be reached". I know.
6a8dbfd7 1096 exec './Configure', @ARGS;
f6647108 1097 die_255("Failed to start Configure: $!");
6a8dbfd7
NC
1098}
1099waitpid $pid, 0
f6647108 1100 or die_255("wait for Configure, pid $pid failed: $!");
6a8dbfd7 1101
86905c1e 1102patch_SH() unless $options{'all-fixups'};
df14fc13 1103apply_fixups($options{'late-fixup'});
bb723266 1104
af7c500f 1105if (-f 'config.sh') {
05ec8abc
NC
1106 # Emulate noextensions if Configure doesn't support it.
1107 fake_noextensions()
1108 if $major < 10 && $defines{noextensions};
d953d40d 1109 system_or_die('./Configure -S');
af7c500f
NC
1110}
1111
0afef97d 1112if ($target =~ /config\.s?h/) {
bf8fb529 1113 match_and_exit($target, @ARGV) if $match && -f $target;
30a13282
NC
1114 report_and_exit(!-f $target, 'could build', 'could not build', $target)
1115 if $options{'test-build'};
1116
18815322
NC
1117 skip("could not build $target") unless -f $target;
1118
30a13282
NC
1119 my $ret = system @ARGV;
1120 report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
dd4e46d7
NC
1121} elsif (!-f 'config.sh') {
1122 # Skip if something went wrong with Configure
1123
1124 skip('could not build config.sh');
1125}
6a8dbfd7 1126
05ec8abc
NC
1127force_manifest_cleanup($missing, $created_dirs)
1128 if $missing;
67382a3b 1129
bfa52998
NC
1130if($options{'force-regen'}
1131 && extract_from_file('Makefile', qr/\bregen_headers\b/)) {
1132 # regen_headers was added in e50aee73b3d4c555, patch.1m for perl5.001
1133 # It's not worth faking it for earlier revisions.
d953d40d 1134 system_or_die('make regen_headers');
bfa52998
NC
1135}
1136
86905c1e
NC
1137unless ($options{'all-fixups'}) {
1138 patch_C();
1139 patch_ext();
1140}
750ce942
NC
1141
1142# Parallel build for miniperl is safe
32ffe018 1143system "$options{make} $j miniperl </dev/null";
750ce942 1144
6c2d645d
NC
1145# This is the file we expect make to create
1146my $expected_file = $target =~ /^test/ ? 't/perl'
750ce942
NC
1147 : $target eq 'Fcntl' ? "lib/auto/Fcntl/Fcntl.$Config{so}"
1148 : $target;
6c2d645d
NC
1149# This is the target we tell make to build in order to get $expected_file
1150my $real_target = $target eq 'Fcntl' ? $expected_file : $target;
750ce942
NC
1151
1152if ($target ne 'miniperl') {
1153 # Nearly all parallel build issues fixed by 5.10.0. Untrustworthy before that.
1154 $j = '' if $major < 10;
1155
1156 if ($real_target eq 'test_prep') {
1157 if ($major < 8) {
1158 # test-prep was added in 5.004_01, 3e3baf6d63945cb6.
1159 # renamed to test_prep in 2001 in 5fe84fd29acaf55c.
1160 # earlier than that, just make test. It will be fast enough.
1161 $real_target = extract_from_file('Makefile.SH',
1162 qr/^(test[-_]prep):/,
1163 'test');
1164 }
1165 }
1166
32ffe018 1167 system "$options{make} $j $real_target </dev/null";
6f8c21fa
NC
1168}
1169
6c2d645d
NC
1170my $expected_file_found = $expected_file =~ /perl$/
1171 ? -x $expected_file : -r $expected_file;
750ce942 1172
63af1e78
NC
1173if ($expected_file_found && $expected_file eq 't/perl') {
1174 # Check that it isn't actually pointing to ../miniperl, which will happen
1175 # if the sanity check ./miniperl -Ilib -MExporter -e '<?>' fails, and
1176 # Makefile tries to run minitest.
1177
1178 # Of course, helpfully sometimes it's called ../perl, other times .././perl
1179 # and who knows if that list is exhaustive...
1180 my ($dev0, $ino0) = stat 't/perl';
1181 my ($dev1, $ino1) = stat 'perl';
1182 unless (defined $dev0 && defined $dev1 && $dev0 == $dev1 && $ino0 == $ino1) {
1183 undef $expected_file_found;
1184 my $link = readlink $expected_file;
1185 warn "'t/perl' => '$link', not 'perl'";
f6647108 1186 die_255("Could not realink t/perl: $!") unless defined $link;
63af1e78
NC
1187 }
1188}
1189
750ce942 1190if ($options{'test-build'}) {
6c2d645d 1191 report_and_exit(!$expected_file_found, 'could build', 'could not build',
750ce942 1192 $real_target);
6c2d645d 1193} elsif (!$expected_file_found) {
750ce942 1194 skip("could not build $real_target");
f50dca98
NC
1195}
1196
bf8fb529 1197match_and_exit($real_target, @ARGV) if $match;
750ce942
NC
1198
1199if (defined $options{'one-liner'}) {
1200 my $exe = $target =~ /^(?:perl$|test)/ ? 'perl' : 'miniperl';
fc4401c6 1201 unshift @ARGV, '-e', $options{'one-liner'};
529d2ac2
NC
1202 foreach (qw(c l w)) {
1203 unshift @ARGV, "-$_" if $options{$_};
1204 }
fc4401c6 1205 unshift @ARGV, "./$exe", '-Ilib';
f50dca98
NC
1206}
1207
e3caab27
NC
1208if (-f $ARGV[0]) {
1209 my $fh = open_or_die($ARGV[0]);
1210 my $line = <$fh>;
1211 unshift @ARGV, $1, '-Ilib'
1212 if $line =~ $run_with_our_perl;
1213}
1214
750ce942
NC
1215# This is what we came here to run:
1216
1217if (exists $Config{ldlibpthname}) {
1218 require Cwd;
1219 my $varname = $Config{ldlibpthname};
1220 my $cwd = Cwd::getcwd();
1221 if (defined $ENV{$varname}) {
1222 $ENV{$varname} = $cwd . $Config{path_sep} . $ENV{$varname};
1223 } else {
1224 $ENV{$varname} = $cwd;
f50dca98 1225 }
750ce942
NC
1226}
1227
1228my $ret = system @ARGV;
1229
1230report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
1231
f2f0a0ff
NC
1232############################################################################
1233#
05ec8abc 1234# Patching, editing and faking routines only below here.
f2f0a0ff
NC
1235#
1236############################################################################
1237
05ec8abc
NC
1238sub fake_noextensions {
1239 edit_file('config.sh', sub {
1240 my @lines = split /\n/, shift;
1241 my @ext = split /\s+/, $defines{noextensions};
1242 foreach (@lines) {
1243 next unless /^extensions=/ || /^dynamic_ext/;
1244 foreach my $ext (@ext) {
1245 s/\b$ext( )?\b/$1/;
1246 }
1247 }
1248 return join "\n", @lines;
1249 });
1250}
1251
1252sub force_manifest {
1253 my (@missing, @created_dirs);
1254 my $fh = open_or_die('MANIFEST');
1255 while (<$fh>) {
1256 next unless /^(\S+)/;
1257 # -d is special case needed (at least) between 27332437a2ed1941 and
1258 # bf3d9ec563d25054^ inclusive, as manifest contains ext/Thread/Thread
1259 push @missing, $1
1260 unless -f $1 || -d $1;
1261 }
1262 close_or_die($fh);
1263
1264 foreach my $pathname (@missing) {
1265 my @parts = split '/', $pathname;
1266 my $leaf = pop @parts;
1267 my $path = '.';
1268 while (@parts) {
1269 $path .= '/' . shift @parts;
1270 next if -d $path;
f6647108 1271 mkdir $path, 0700 or die_255("Can't create $path: $!");
05ec8abc
NC
1272 unshift @created_dirs, $path;
1273 }
1274 $fh = open_or_die($pathname, '>');
1275 close_or_die($fh);
f6647108 1276 chmod 0, $pathname or die_255("Can't chmod 0 $pathname: $!");
05ec8abc
NC
1277 }
1278 return \@missing, \@created_dirs;
1279}
1280
1281sub force_manifest_cleanup {
1282 my ($missing, $created_dirs) = @_;
1283 # This is probably way too paranoid:
1284 my @errors;
1285 require Fcntl;
1286 foreach my $file (@$missing) {
1287 my (undef, undef, $mode, undef, undef, undef, undef, $size)
1288 = stat $file;
1289 if (!defined $mode) {
1290 push @errors, "Added file $file has been deleted by Configure";
1291 next;
1292 }
1293 if (Fcntl::S_IMODE($mode) != 0) {
1294 push @errors,
1295 sprintf 'Added file %s had mode changed by Configure to %03o',
1296 $file, $mode;
1297 }
1298 if ($size != 0) {
1299 push @errors,
1300 "Added file $file had sized changed by Configure to $size";
1301 }
f6647108 1302 unlink $file or die_255("Can't unlink $file: $!");
05ec8abc
NC
1303 }
1304 foreach my $dir (@$created_dirs) {
f6647108 1305 rmdir $dir or die_255("Can't rmdir $dir: $!");
05ec8abc
NC
1306 }
1307 skip("@errors")
1308 if @errors;
1309}
1310
750ce942
NC
1311sub patch_Configure {
1312 if ($major < 1) {
1313 if (extract_from_file('Configure',
1314 qr/^\t\t\*=\*\) echo "\$1" >> \$optdef;;$/)) {
1315 # This is " Spaces now allowed in -D command line options.",
1316 # part of commit ecfc54246c2a6f42
1317 apply_patch(<<'EOPATCH');
1318diff --git a/Configure b/Configure
1319index 3d3b38d..78ffe16 100755
1320--- a/Configure
1321+++ b/Configure
1322@@ -652,7 +777,8 @@ while test $# -gt 0; do
1323 echo "$me: use '-U symbol=', not '-D symbol='." >&2
1324 echo "$me: ignoring -D $1" >&2
1325 ;;
1326- *=*) echo "$1" >> $optdef;;
1327+ *=*) echo "$1" | \
1328+ sed -e "s/'/'\"'\"'/g" -e "s/=\(.*\)/='\1'/" >> $optdef;;
1329 *) echo "$1='define'" >> $optdef;;
1330 esac
1331 shift
1332EOPATCH
1333 }
1334
1335 if (extract_from_file('Configure', qr/^if \$contains 'd_namlen' \$xinc\b/)) {
1336 # Configure's original simple "grep" for d_namlen falls foul of the
1337 # approach taken by the glibc headers:
1338 # #ifdef _DIRENT_HAVE_D_NAMLEN
1339 # # define _D_EXACT_NAMLEN(d) ((d)->d_namlen)
1340 #
1341 # where _DIRENT_HAVE_D_NAMLEN is not defined on Linux.
1342 # This is also part of commit ecfc54246c2a6f42
1343 apply_patch(<<'EOPATCH');
1344diff --git a/Configure b/Configure
1345index 3d3b38d..78ffe16 100755
1346--- a/Configure
1347+++ b/Configure
1348@@ -3935,7 +4045,8 @@ $rm -f try.c
1349
1350 : see if the directory entry stores field length
1351 echo " "
1352-if $contains 'd_namlen' $xinc >/dev/null 2>&1; then
1353+$cppstdin $cppflags $cppminus < "$xinc" > try.c
1354+if $contains 'd_namlen' try.c >/dev/null 2>&1; then
1355 echo "Good, your directory entry keeps length information in d_namlen." >&4
1356 val="$define"
1357 else
1358EOPATCH
1359 }
f50dca98 1360 }
750ce942
NC
1361
1362 if ($major < 2
1363 && !extract_from_file('Configure',
1364 qr/Try to guess additional flags to pick up local libraries/)) {
1365 my $mips = extract_from_file('Configure',
1366 qr!(''\) if (?:\./)?mips; then)!);
1367 # This is part of perl-5.001n. It's needed, to add -L/usr/local/lib to
730ad6b9
DS
1368 # the ld flags if libraries are found there. It shifts the code to set
1369 # up libpth earlier, and then adds the code to add libpth entries to
750ce942
NC
1370 # ldflags
1371 # mips was changed to ./mips in ecfc54246c2a6f42, perl5.000 patch.0g
1372 apply_patch(sprintf <<'EOPATCH', $mips);
1373diff --git a/Configure b/Configure
1374index 53649d5..0635a6e 100755
1375--- a/Configure
1376+++ b/Configure
1377@@ -2749,6 +2749,52 @@ EOM
1378 ;;
1379 esac
f50dca98 1380
750ce942
NC
1381+: Set private lib path
1382+case "$plibpth" in
1383+'') if ./mips; then
1384+ plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
1385+ fi;;
1386+esac
1387+case "$libpth" in
1388+' ') dlist='';;
1389+'') dlist="$plibpth $glibpth";;
1390+*) dlist="$libpth";;
1391+esac
1392+
1393+: Now check and see which directories actually exist, avoiding duplicates
1394+libpth=''
1395+for xxx in $dlist
1396+do
1397+ if $test -d $xxx; then
1398+ case " $libpth " in
1399+ *" $xxx "*) ;;
1400+ *) libpth="$libpth $xxx";;
1401+ esac
1402+ fi
1403+done
1404+$cat <<'EOM'
1405+
1406+Some systems have incompatible or broken versions of libraries. Among
1407+the directories listed in the question below, please remove any you
1408+know not to be holding relevant libraries, and add any that are needed.
1409+Say "none" for none.
1410+
1411+EOM
1412+case "$libpth" in
1413+'') dflt='none';;
1414+*)
1415+ set X $libpth
1416+ shift
1417+ dflt=${1+"$@"}
1418+ ;;
1419+esac
1420+rp="Directories to use for library searches?"
1421+. ./myread
1422+case "$ans" in
1423+none) libpth=' ';;
1424+*) libpth="$ans";;
1425+esac
1426+
1427 : flags used in final linking phase
1428 case "$ldflags" in
1429 '') if ./venix; then
1430@@ -2765,6 +2811,23 @@ case "$ldflags" in
1431 ;;
1432 *) dflt="$ldflags";;
1433 esac
1434+
1435+: Possible local library directories to search.
1436+loclibpth="/usr/local/lib /opt/local/lib /usr/gnu/lib"
1437+loclibpth="$loclibpth /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib"
1438+
1439+: Try to guess additional flags to pick up local libraries.
1440+for thislibdir in $libpth; do
1441+ case " $loclibpth " in
1442+ *" $thislibdir "*)
1443+ case "$dflt " in
1444+ "-L$thislibdir ") ;;
1445+ *) dflt="$dflt -L$thislibdir" ;;
1446+ esac
1447+ ;;
1448+ esac
1449+done
1450+
1451 echo " "
1452 rp="Any additional ld flags (NOT including libraries)?"
1453 . ./myread
1454@@ -2828,52 +2891,6 @@ n) echo "OK, that should do.";;
1455 esac
1456 $rm -f try try.* core
1457
1458-: Set private lib path
1459-case "$plibpth" in
1460-%s
1461- plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
1462- fi;;
1463-esac
1464-case "$libpth" in
1465-' ') dlist='';;
1466-'') dlist="$plibpth $glibpth";;
1467-*) dlist="$libpth";;
1468-esac
1469-
1470-: Now check and see which directories actually exist, avoiding duplicates
1471-libpth=''
1472-for xxx in $dlist
1473-do
1474- if $test -d $xxx; then
1475- case " $libpth " in
1476- *" $xxx "*) ;;
1477- *) libpth="$libpth $xxx";;
1478- esac
1479- fi
1480-done
1481-$cat <<'EOM'
f50dca98 1482-
750ce942
NC
1483-Some systems have incompatible or broken versions of libraries. Among
1484-the directories listed in the question below, please remove any you
1485-know not to be holding relevant libraries, and add any that are needed.
1486-Say "none" for none.
1487-
1488-EOM
1489-case "$libpth" in
1490-'') dflt='none';;
1491-*)
1492- set X $libpth
1493- shift
1494- dflt=${1+"$@"}
1495- ;;
1496-esac
1497-rp="Directories to use for library searches?"
1498-. ./myread
1499-case "$ans" in
1500-none) libpth=' ';;
1501-*) libpth="$ans";;
1502-esac
1503-
1504 : compute shared library extension
1505 case "$so" in
1506 '')
f50dca98
NC
1507EOPATCH
1508 }
686af304 1509
750ce942
NC
1510 if ($major < 5 && extract_from_file('Configure',
1511 qr!if \$cc \$ccflags try\.c -o try >/dev/null 2>&1; then!)) {
1512 # Analogous to the more general fix of dfe9444ca7881e71
1513 # Without this flags such as -m64 may not be passed to this compile,
1514 # which results in a byteorder of '1234' instead of '12345678', which
1515 # can then cause crashes.
686af304 1516
750ce942
NC
1517 if (extract_from_file('Configure', qr/xxx_prompt=y/)) {
1518 # 8e07c86ebc651fe9 or later
1519 # ("This is my patch patch.1n for perl5.001.")
1520 apply_patch(<<'EOPATCH');
1521diff --git a/Configure b/Configure
1522index 62249dd..c5c384e 100755
1523--- a/Configure
1524+++ b/Configure
1525@@ -8247,7 +8247,7 @@ main()
1526 }
1527 EOCP
1528 xxx_prompt=y
1529- if $cc $ccflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
1530+ if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
1531 dflt=`./try`
1532 case "$dflt" in
1533 [1-4][1-4][1-4][1-4]|12345678|87654321)
1534EOPATCH
1535 } else {
1536 apply_patch(<<'EOPATCH');
1537diff --git a/Configure b/Configure
1538index 53649d5..f1cd64a 100755
1539--- a/Configure
1540+++ b/Configure
1541@@ -6362,7 +6362,7 @@ main()
1542 printf("\n");
1543 }
1544 EOCP
1545- if $cc $ccflags try.c -o try >/dev/null 2>&1 ; then
1546+ if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 ; then
1547 dflt=`./try`
1548 case "$dflt" in
1549 ????|????????) echo "(The test program ran ok.)";;
1550EOPATCH
1551 }
1552 }
9a999a97 1553
750ce942
NC
1554 if ($major < 6 && !extract_from_file('Configure',
1555 qr!^\t-A\)$!)) {
1556 # This adds the -A option to Configure, which is incredibly useful
1557 # Effectively this is commits 02e93a22d20fc9a5, 5f83a3e9d818c3ad,
1558 # bde6b06b2c493fef, f7c3111703e46e0c and 2 lines of trailing whitespace
1559 # removed by 613d6c3e99b9decc, but applied at slightly different
1560 # locations to ensure a clean patch back to 5.000
1561 # Note, if considering patching to the intermediate revisions to fix
1562 # bugs in -A handling, f7c3111703e46e0c is from 2002, and hence
1563 # $major == 8
1564
1565 # To add to the fun, early patches add -K and -O options, and it's not
1566 # trivial to get patch to put the C<. ./posthint.sh> in the right place
1567 edit_file('Configure', sub {
1568 my $code = shift;
1569 $code =~ s/(optstr = ")([^"]+";\s*# getopt-style specification)/$1A:$2/
f6647108 1570 or die_255("Substitution failed");
750ce942
NC
1571 $code =~ s!^(: who configured the system)!
1572touch posthint.sh
1573. ./posthint.sh
2526f4b8 1574
750ce942 1575$1!ms
f6647108 1576 or die_255("Substitution failed");
750ce942
NC
1577 return $code;
1578 });
1579 apply_patch(<<'EOPATCH');
1580diff --git a/Configure b/Configure
1581index 4b55fa6..60c3c64 100755
1582--- a/Configure
1583+++ b/Configure
1584@@ -1150,6 +1150,7 @@ set X `for arg in "$@"; do echo "X$arg"; done |
1585 eval "set $*"
1586 shift
1587 rm -f options.awk
1588+rm -f posthint.sh
1589
1590 : set up default values
1591 fastread=''
1592@@ -1172,6 +1173,56 @@ while test $# -gt 0; do
1593 case "$1" in
1594 -d) shift; fastread=yes;;
1595 -e) shift; alldone=cont;;
1596+ -A)
1597+ shift
1598+ xxx=''
1599+ yyy="$1"
1600+ zzz=''
1601+ uuu=undef
1602+ case "$yyy" in
1603+ *=*) zzz=`echo "$yyy"|sed 's!=.*!!'`
1604+ case "$zzz" in
1605+ *:*) zzz='' ;;
1606+ *) xxx=append
1607+ zzz=" "`echo "$yyy"|sed 's!^[^=]*=!!'`
1608+ yyy=`echo "$yyy"|sed 's!=.*!!'` ;;
1609+ esac
1610+ ;;
1611+ esac
1612+ case "$xxx" in
1613+ '') case "$yyy" in
1614+ *:*) xxx=`echo "$yyy"|sed 's!:.*!!'`
1615+ yyy=`echo "$yyy"|sed 's!^[^:]*:!!'`
1616+ zzz=`echo "$yyy"|sed 's!^[^=]*=!!'`
1617+ yyy=`echo "$yyy"|sed 's!=.*!!'` ;;
1618+ *) xxx=`echo "$yyy"|sed 's!:.*!!'`
1619+ yyy=`echo "$yyy"|sed 's!^[^:]*:!!'` ;;
1620+ esac
1621+ ;;
1622+ esac
1623+ case "$xxx" in
1624+ append)
1625+ echo "$yyy=\"\${$yyy}$zzz\"" >> posthint.sh ;;
1626+ clear)
1627+ echo "$yyy=''" >> posthint.sh ;;
1628+ define)
1629+ case "$zzz" in
1630+ '') zzz=define ;;
1631+ esac
1632+ echo "$yyy='$zzz'" >> posthint.sh ;;
1633+ eval)
1634+ echo "eval \"$yyy=$zzz\"" >> posthint.sh ;;
1635+ prepend)
1636+ echo "$yyy=\"$zzz\${$yyy}\"" >> posthint.sh ;;
1637+ undef)
1638+ case "$zzz" in
1639+ '') zzz="$uuu" ;;
1640+ esac
1641+ echo "$yyy=$zzz" >> posthint.sh ;;
1642+ *) echo "$me: unknown -A command '$xxx', ignoring -A $1" >&2 ;;
1643+ esac
1644+ shift
1645+ ;;
1646 -f)
1647 shift
1648 cd ..
1649EOPATCH
1650 }
9a999a97 1651
d1ac19b7
NC
1652 if ($major < 8 && $^O eq 'aix') {
1653 edit_file('Configure', sub {
1654 my $code = shift;
1655 # Replicate commit a8c676c69574838b
1656 # Whitespace allowed at the ends of /lib/syscalls.exp lines
1657 # and half of commit c6912327ae30e6de
1658 # AIX syscalls.exp scan: the syscall might be marked 32, 3264, or 64
1659 $code =~ s{(\bsed\b.*\bsyscall)(?:\[0-9\]\*)?(\$.*/lib/syscalls\.exp)}
1660 {$1 . "[0-9]*[ \t]*" . $2}e;
1661 return $code;
1662 });
1663 }
1664
750ce942
NC
1665 if ($major < 8 && !extract_from_file('Configure',
1666 qr/^\t\tif test ! -t 0; then$/)) {
1667 # Before dfe9444ca7881e71, Configure would refuse to run if stdin was
1668 # not a tty. With that commit, the tty requirement was dropped for -de
1669 # and -dE
1670 # Commit aaeb8e512e8e9e14 dropped the tty requirement for -S
1671 # For those older versions, it's probably easiest if we simply remove
1672 # the sanity test.
1673 edit_file('Configure', sub {
1674 my $code = shift;
1675 $code =~ s/test ! -t 0/test Perl = rules/;
1676 return $code;
1677 });
6a8dbfd7 1678 }
6a8dbfd7 1679
750ce942
NC
1680 if ($major == 8 || $major == 9) {
1681 # Fix symbol detection to that of commit 373dfab3839ca168 if it's any
1682 # intermediate version 5129fff43c4fe08c or later, as the intermediate
1683 # versions don't work correctly on (at least) Sparc Linux.
1684 # 5129fff43c4fe08c adds the first mention of mistrustnm.
1685 # 373dfab3839ca168 removes the last mention of lc=""
1686 edit_file('Configure', sub {
1687 my $code = shift;
1688 return $code
1689 if $code !~ /\btc="";/; # 373dfab3839ca168 or later
1690 return $code
1691 if $code !~ /\bmistrustnm\b/; # before 5129fff43c4fe08c
1692 my $fixed = <<'EOC';
6a8dbfd7 1693
750ce942
NC
1694: is a C symbol defined?
1695csym='tlook=$1;
1696case "$3" in
1697-v) tf=libc.tmp; tdc="";;
1698-a) tf=libc.tmp; tdc="[]";;
1699*) tlook="^$1\$"; tf=libc.list; tdc="()";;
1700esac;
1701tx=yes;
1702case "$reuseval-$4" in
1703true-) ;;
1704true-*) tx=no; eval "tval=\$$4"; case "$tval" in "") tx=yes;; esac;;
1705esac;
1706case "$tx" in
1707yes)
1708 tval=false;
1709 if $test "$runnm" = true; then
1710 if $contains $tlook $tf >/dev/null 2>&1; then
1711 tval=true;
1712 elif $test "$mistrustnm" = compile -o "$mistrustnm" = run; then
1713 echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
1714 $cc -o try $optimize $ccflags $ldflags try.c >/dev/null 2>&1 $libs && tval=true;
1715 $test "$mistrustnm" = run -a -x try && { $run ./try$_exe >/dev/null 2>&1 || tval=false; };
1716 $rm -f try$_exe try.c core core.* try.core;
1717 fi;
1718 else
1719 echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
1720 $cc -o try $optimize $ccflags $ldflags try.c $libs >/dev/null 2>&1 && tval=true;
1721 $rm -f try$_exe try.c;
1722 fi;
1723 ;;
1724*)
1725 case "$tval" in
1726 $define) tval=true;;
1727 *) tval=false;;
1728 esac;
1729 ;;
1730esac;
1731eval "$2=$tval"'
67382a3b 1732
750ce942
NC
1733EOC
1734 $code =~ s/\n: is a C symbol defined\?\n.*?\neval "\$2=\$tval"'\n\n/$fixed/sm
f6647108 1735 or die_255("substitution failed");
750ce942
NC
1736 return $code;
1737 });
1738 }
1739
1740 if ($major < 10
1741 && extract_from_file('Configure', qr/^set malloc\.h i_malloc$/)) {
1742 # This is commit 01d07975f7ef0e7d, trimmed, with $compile inlined as
1743 # prior to bd9b35c97ad661cc Configure had the malloc.h test before the
1744 # definition of $compile.
1745 apply_patch(<<'EOPATCH');
1746diff --git a/Configure b/Configure
1747index 3d2e8b9..6ce7766 100755
1748--- a/Configure
1749+++ b/Configure
1750@@ -6743,5 +6743,22 @@ set d_dosuid
1751
1752 : see if this is a malloc.h system
1753-set malloc.h i_malloc
1754-eval $inhdr
1755+: we want a real compile instead of Inhdr because some systems have a
1756+: malloc.h that just gives a compile error saying to use stdlib.h instead
1757+echo " "
1758+$cat >try.c <<EOCP
1759+#include <stdlib.h>
1760+#include <malloc.h>
1761+int main () { return 0; }
1762+EOCP
1763+set try
1764+if $cc $optimize $ccflags $ldflags -o try $* try.c $libs > /dev/null 2>&1; then
1765+ echo "<malloc.h> found." >&4
1766+ val="$define"
1767+else
1768+ echo "<malloc.h> NOT found." >&4
1769+ val="$undef"
1770+fi
1771+$rm -f try.c try
1772+set i_malloc
1773+eval $setvar
1774
1775EOPATCH
1776 }
67382a3b 1777}
6a8dbfd7 1778
750ce942
NC
1779sub patch_hints {
1780 if ($^O eq 'freebsd') {
1781 # There are rather too many version-specific FreeBSD hints fixes to
1782 # patch individually. Also, more than once the FreeBSD hints file has
1783 # been written in what turned out to be a rather non-future-proof style,
1784 # with case statements treating the most recent version as the
1785 # exception, instead of treating previous versions' behaviour explicitly
1786 # and changing the default to cater for the current behaviour. (As
1787 # strangely, future versions inherit the current behaviour.)
1788 checkout_file('hints/freebsd.sh');
1789 } elsif ($^O eq 'darwin') {
1790 if ($major < 8) {
1791 # We can't build on darwin without some of the data in the hints
1792 # file. Probably less surprising to use the earliest version of
1793 # hints/darwin.sh and then edit in place just below, than use
1794 # blead's version, as that would create a discontinuity at
1795 # f556e5b971932902 - before it, hints bugs would be "fixed", after
1796 # it they'd resurface. This way, we should give the illusion of
1797 # monotonic bug fixing.
1798 my $faking_it;
1799 if (!-f 'hints/darwin.sh') {
1800 checkout_file('hints/darwin.sh', 'f556e5b971932902');
1801 ++$faking_it;
1802 }
0afef97d 1803
750ce942
NC
1804 edit_file('hints/darwin.sh', sub {
1805 my $code = shift;
1806 # Part of commit 8f4f83badb7d1ba9, which mostly undoes
1807 # commit 0511a818910f476c.
1808 $code =~ s/^cppflags='-traditional-cpp';$/cppflags="\${cppflags} -no-cpp-precomp"/m;
1809 # commit 14c11978e9b52e08/803bb6cc74d36a3f
1810 # Without this, code in libperl.bundle links against op.o
1811 # in preference to opmini.o on the linker command line,
1812 # and hence miniperl tries to use File::Glob instead of
1813 # csh
1814 $code =~ s/^(lddlflags=)/ldflags="\${ldflags} -flat_namespace"\n$1/m;
1815 # f556e5b971932902 also patches Makefile.SH with some
1816 # special case code to deal with useshrplib for darwin.
1817 # Given that post 5.8.0 the darwin hints default was
1818 # changed to false, and it would be very complex to splice
1819 # in that code in various versions of Makefile.SH back
1820 # to 5.002, lets just turn it off.
1821 $code =~ s/^useshrplib='true'/useshrplib='false'/m
1822 if $faking_it;
1f1c8096
NC
1823
1824 # Part of commit d235852b65d51c44
1825 # Don't do this on a case sensitive HFS+ partition, as it
1826 # breaks the build for 5.003 and earlier.
1827 if ($case_insensitive
1828 && $code !~ /^firstmakefile=GNUmakefile/) {
1829 $code .= "\nfirstmakefile=GNUmakefile;\n";
1830 }
1831
750ce942
NC
1832 return $code;
1833 });
1834 }
1835 } elsif ($^O eq 'netbsd') {
1836 if ($major < 6) {
1837 # These are part of commit 099685bc64c7dbce
1838 edit_file('hints/netbsd.sh', sub {
1839 my $code = shift;
1840 my $fixed = <<'EOC';
1841case "$osvers" in
18420.9|0.8*)
1843 usedl="$undef"
1844 ;;
1845*)
1846 if [ -f /usr/libexec/ld.elf_so ]; then
1847 d_dlopen=$define
1848 d_dlerror=$define
1849 ccdlflags="-Wl,-E -Wl,-R${PREFIX}/lib $ccdlflags"
1850 cccdlflags="-DPIC -fPIC $cccdlflags"
1851 lddlflags="--whole-archive -shared $lddlflags"
1852 elif [ "`uname -m`" = "pmax" ]; then
9f1d18fe 1853# NetBSD 1.3 and 1.3.1 on pmax shipped an 'old' ld.so, which will not work.
750ce942
NC
1854 d_dlopen=$undef
1855 elif [ -f /usr/libexec/ld.so ]; then
1856 d_dlopen=$define
1857 d_dlerror=$define
1858 ccdlflags="-Wl,-R${PREFIX}/lib $ccdlflags"
1859# we use -fPIC here because -fpic is *NOT* enough for some of the
1860# extensions like Tk on some netbsd platforms (the sparc is one)
1861 cccdlflags="-DPIC -fPIC $cccdlflags"
1862 lddlflags="-Bforcearchive -Bshareable $lddlflags"
1863 else
1864 d_dlopen=$undef
1865 fi
1866 ;;
1867esac
1868EOC
1869 $code =~ s/^case "\$osvers" in\n0\.9\|0\.8.*?^esac\n/$fixed/ms;
1870 return $code;
1871 });
1872 }
1873 } elsif ($^O eq 'openbsd') {
1874 if ($major < 8) {
1875 checkout_file('hints/openbsd.sh', '43051805d53a3e4c')
1876 unless -f 'hints/openbsd.sh';
1877 my $which = extract_from_file('hints/openbsd.sh',
1878 qr/# from (2\.8|3\.1) onwards/,
1879 '');
1880 if ($which eq '') {
1881 my $was = extract_from_file('hints/openbsd.sh',
1882 qr/(lddlflags="(?:-Bforcearchive )?-Bshareable)/);
1883 # This is commit 154d43cbcf57271c and parts of 5c75dbfa77b0949c
1884 # and 29b5585702e5e025
1885 apply_patch(sprintf <<'EOPATCH', $was);
1886diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1887index a7d8bf2..5b79709 100644
1888--- a/hints/openbsd.sh
1889+++ b/hints/openbsd.sh
1890@@ -37,7 +37,25 @@ OpenBSD.alpha|OpenBSD.mips|OpenBSD.powerpc|OpenBSD.vax)
1891 # we use -fPIC here because -fpic is *NOT* enough for some of the
1892 # extensions like Tk on some OpenBSD platforms (ie: sparc)
1893 cccdlflags="-DPIC -fPIC $cccdlflags"
1894- %s $lddlflags"
1895+ case "$osvers" in
1896+ [01].*|2.[0-7]|2.[0-7].*)
1897+ lddlflags="-Bshareable $lddlflags"
1898+ ;;
1899+ 2.[8-9]|3.0)
1900+ ld=${cc:-cc}
1901+ lddlflags="-shared -fPIC $lddlflags"
1902+ ;;
1903+ *) # from 3.1 onwards
1904+ ld=${cc:-cc}
1905+ lddlflags="-shared -fPIC $lddlflags"
1906+ libswanted=`echo $libswanted | sed 's/ dl / /'`
1907+ ;;
1908+ esac
1909+
1910+ # We need to force ld to export symbols on ELF platforms.
1911+ # Without this, dlopen() is crippled.
1912+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1913+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1914 ;;
1915 esac
1916
1917EOPATCH
1918 } elsif ($which eq '2.8') {
1919 # This is parts of 5c75dbfa77b0949c and 29b5585702e5e025, and
1920 # possibly eb9cd59d45ad2908
1921 my $was = extract_from_file('hints/openbsd.sh',
1922 qr/lddlflags="(-shared(?: -fPIC)?) \$lddlflags"/);
0afef97d 1923
750ce942
NC
1924 apply_patch(sprintf <<'EOPATCH', $was);
1925--- a/hints/openbsd.sh 2011-10-21 17:25:20.000000000 +0200
1926+++ b/hints/openbsd.sh 2011-10-21 16:58:43.000000000 +0200
1927@@ -44,11 +44,21 @@
1928 [01].*|2.[0-7]|2.[0-7].*)
1929 lddlflags="-Bshareable $lddlflags"
1930 ;;
1931- *) # from 2.8 onwards
1932+ 2.[8-9]|3.0)
1933 ld=${cc:-cc}
1934- lddlflags="%s $lddlflags"
1935+ lddlflags="-shared -fPIC $lddlflags"
1936+ ;;
1937+ *) # from 3.1 onwards
1938+ ld=${cc:-cc}
1939+ lddlflags="-shared -fPIC $lddlflags"
1940+ libswanted=`echo $libswanted | sed 's/ dl / /'`
1941 ;;
1942 esac
1943+
1944+ # We need to force ld to export symbols on ELF platforms.
1945+ # Without this, dlopen() is crippled.
1946+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1947+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1948 ;;
1949 esac
1950
1951EOPATCH
1952 } elsif ($which eq '3.1'
1953 && !extract_from_file('hints/openbsd.sh',
1954 qr/We need to force ld to export symbols on ELF platforms/)) {
1955 # This is part of 29b5585702e5e025
1956 apply_patch(<<'EOPATCH');
1957diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1958index c6b6bc9..4839d04 100644
1959--- a/hints/openbsd.sh
1960+++ b/hints/openbsd.sh
1961@@ -54,6 +54,11 @@ alpha-2.[0-8]|mips-*|vax-*|powerpc-2.[0-7]|m88k-*)
1962 libswanted=`echo $libswanted | sed 's/ dl / /'`
1963 ;;
1964 esac
1965+
1966+ # We need to force ld to export symbols on ELF platforms.
1967+ # Without this, dlopen() is crippled.
1968+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1969+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1970 ;;
1971 esac
1972
1973EOPATCH
1974 }
1975 }
1976 } elsif ($^O eq 'linux') {
1977 if ($major < 1) {
1978 # sparc linux seems to need the -Dbool=char -DHAS_BOOL part of
1979 # perl5.000 patch.0n: [address Configure and build issues]
1980 edit_file('hints/linux.sh', sub {
1981 my $code = shift;
1982 $code =~ s!-I/usr/include/bsd!-Dbool=char -DHAS_BOOL!g;
1983 return $code;
1984 });
1985 }
915f531b 1986
750ce942
NC
1987 if ($major <= 9) {
1988 if (`uname -sm` =~ qr/^Linux sparc/) {
1989 if (extract_from_file('hints/linux.sh', qr/sparc-linux/)) {
1990 # Be sure to use -fPIC not -fpic on Linux/SPARC
1991 apply_commit('f6527d0ef0c13ad4');
1992 } elsif(!extract_from_file('hints/linux.sh',
1993 qr/^sparc-linux\)$/)) {
1994 my $fh = open_or_die('hints/linux.sh', '>>');
f6647108 1995 print $fh <<'EOT' or die_255($!);
750ce942
NC
1996
1997case "`uname -m`" in
1998sparc*)
1999 case "$cccdlflags" in
2000 *-fpic*) cccdlflags="`echo $cccdlflags|sed 's/-fpic/-fPIC/'`" ;;
2001 *) cccdlflags="$cccdlflags -fPIC" ;;
2002 esac
2003 ;;
2004esac
2005EOT
2006 close_or_die($fh);
2007 }
2008 }
2009 }
915f531b
NC
2010 }
2011}
2012
bb723266
NC
2013sub patch_SH {
2014 # Cwd.xs added in commit 0d2079faa739aaa9. Cwd.pm moved to ext/ 8 years
2015 # later in commit 403f501d5b37ebf0
2016 if ($major > 0 && <*/Cwd/Cwd.xs>) {
2017 if ($major < 10
2018 && !extract_from_file('Makefile.SH', qr/^extra_dep=''$/)) {
2019 # The Makefile.PL for Unicode::Normalize needs
2020 # lib/unicore/CombiningClass.pl. Even without a parallel build, we
2021 # need a dependency to ensure that it builds. This is a variant of
2022 # commit 9f3ef600c170f61e. Putting this for earlier versions gives
2023 # us a spot on which to hang the edits below
2024 apply_patch(<<'EOPATCH');
2025diff --git a/Makefile.SH b/Makefile.SH
2026index f61d0db..6097954 100644
2027--- a/Makefile.SH
2028+++ b/Makefile.SH
2029@@ -155,10 +155,20 @@ esac
2030
2031 : Prepare dependency lists for Makefile.
2032 dynamic_list=' '
2033+extra_dep=''
2034 for f in $dynamic_ext; do
2035 : the dependency named here will never exist
2036 base=`echo "$f" | sed 's/.*\///'`
2037- dynamic_list="$dynamic_list lib/auto/$f/$base.$dlext"
2038+ this_target="lib/auto/$f/$base.$dlext"
2039+ dynamic_list="$dynamic_list $this_target"
2040+
2041+ : Parallel makes reveal that we have some interdependencies
2042+ case $f in
2043+ Math/BigInt/FastCalc) extra_dep="$extra_dep
2044+$this_target: lib/auto/List/Util/Util.$dlext" ;;
2045+ Unicode/Normalize) extra_dep="$extra_dep
2046+$this_target: lib/unicore/CombiningClass.pl" ;;
2047+ esac
2048 done
2049
2050 static_list=' '
2051@@ -987,2 +997,9 @@ n_dummy $(nonxs_ext): miniperl$(EXE_EXT) preplibrary $(DYNALOADER) FORCE
2052 @$(LDLIBPTH) sh ext/util/make_ext nonxs $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL)
2053+!NO!SUBS!
2054+
2055+$spitshell >>Makefile <<EOF
2056+$extra_dep
2057+EOF
2058+
2059+$spitshell >>Makefile <<'!NO!SUBS!'
2060
2061EOPATCH
2062 }
c0960282 2063
67bec938
NC
2064 if ($major == 15 && $^O !~ /^(linux|darwin|.*bsd)$/
2065 && extract_from_file('Makefile.SH', qr/^V.* \?= /)) {
2066 # Remove the GNU-make-ism (which the BSD makes also support, but
2067 # most other makes choke on)
2068 apply_patch(<<'EOPATCH');
2069diff --git a/Makefile.SH b/Makefile.SH
2070index 94952bd..13e9001 100755
2071--- a/Makefile.SH
2072+++ b/Makefile.SH
2073@@ -338,8 +338,8 @@ linux*|darwin)
2074 $spitshell >>$Makefile <<!GROK!THIS!
2075 # If you're going to use valgrind and it can't be invoked as plain valgrind
2076 # then you'll need to change this, or override it on the make command line.
2077-VALGRIND ?= valgrind
2078-VG_TEST ?= ./perl -e 1 2>/dev/null
2079+VALGRIND = valgrind
2080+VG_TEST = ./perl -e 1 2>/dev/null
2081
2082 !GROK!THIS!
2083 ;;
2084EOPATCH
2085 }
2086
c0960282
NC
2087 if ($major == 11) {
2088 if (extract_from_file('patchlevel.h',
2089 qr/^#include "unpushed\.h"/)) {
2090 # I had thought it easier to detect when building one of the 52
2091 # commits with the original method of incorporating the git
2092 # revision and drop parallel make flags. Commits shown by
2093 # git log 46807d8e809cc127^..dcff826f70bf3f64^ ^d4fb0a1f15d1a1c4
2094 # However, it's not actually possible to make miniperl for that
2095 # configuration as-is, because the file .patchnum is only made
2096 # as a side effect of target 'all'
2097 # I also don't think that it's "safe" to simply run
2098 # make_patchnum.sh before the build. We need the proper
2099 # dependency rules in the Makefile to *stop* it being run again
2100 # at the wrong time.
2101 # This range is important because contains the commit that
2102 # merges Schwern's y2038 work.
2103 apply_patch(<<'EOPATCH');
2104diff --git a/Makefile.SH b/Makefile.SH
2105index 9ad8b6f..106e721 100644
2106--- a/Makefile.SH
2107+++ b/Makefile.SH
2108@@ -540,9 +544,14 @@ sperl.i: perl.c $(h)
2109
2110 .PHONY: all translators utilities make_patchnum
2111
2112-make_patchnum:
2113+make_patchnum: lib/Config_git.pl
2114+
2115+lib/Config_git.pl: make_patchnum.sh
2116 sh $(shellflags) make_patchnum.sh
2117
2118+# .patchnum, unpushed.h and lib/Config_git.pl are built by make_patchnum.sh
2119+unpushed.h .patchnum: lib/Config_git.pl
2120+
2121 # make sure that we recompile perl.c if .patchnum changes
2122 perl$(OBJ_EXT): .patchnum unpushed.h
2123
2124EOPATCH
2125 } elsif (-f '.gitignore'
2126 && extract_from_file('.gitignore', qr/^\.patchnum$/)) {
2127 # 8565263ab8a47cda to 46807d8e809cc127^ inclusive.
2128 edit_file('Makefile.SH', sub {
2129 my $code = shift;
2130 $code =~ s/^make_patchnum:\n/make_patchnum: .patchnum
2131
2132.sha1: .patchnum
2133
2134.patchnum: make_patchnum.sh
2135/m;
2136 return $code;
2137 });
74adbdfa
NC
2138 } elsif (-f 'lib/.gitignore'
2139 && extract_from_file('lib/.gitignore',
2140 qr!^/Config_git.pl!)
2141 && !extract_from_file('Makefile.SH',
2142 qr/^uudmap\.h.*:bitcount.h$/)) {
2143 # Between commits and dcff826f70bf3f64 and 0f13ebd5d71f8177^
2144 edit_file('Makefile.SH', sub {
2145 my $code = shift;
2146 # Bug introduced by 344af494c35a9f0f
2147 # fixed in 0f13ebd5d71f8177
2148 $code =~ s{^(pod/perlapi\.pod) (pod/perlintern\.pod): }
2149 {$1: $2\n\n$2: }m;
2150 # Bug introduced by efa50c51e3301a2c
2151 # fixed in 0f13ebd5d71f8177
2152 $code =~ s{^(uudmap\.h) (bitcount\.h): }
2153 {$1: $2\n\n$2: }m;
93a0b6a3
NC
2154
2155 # The rats nest of getting git_version.h correct
2156
2157 if ($code =~ s{git_version\.h: stock_git_version\.h
2158\tcp stock_git_version\.h git_version\.h}
2159 {}m) {
2160 # before 486cd780047ff224
2161
2162 # We probably can't build between
2163 # 953f6acfa20ec275^ and 8565263ab8a47cda
2164 # inclusive, but all commits in that range
2165 # relate to getting make_patchnum.sh working,
2166 # so it is extremely unlikely to be an
2167 # interesting bisect target. They will skip.
2168
2169 # No, don't spawn a submake if
2170 # make_patchnum.sh or make_patchnum.pl fails
2171 $code =~ s{\|\| \$\(MAKE\) miniperl.*}
2172 {}m;
2173 $code =~ s{^\t(sh.*make_patchnum\.sh.*)}
2174 {\t-$1}m;
2175
2176 # Use an external perl to run make_patchnum.pl
2177 # because miniperl still depends on
2178 # git_version.h
2179 $code =~ s{^\t.*make_patchnum\.pl}
2180 {\t-$^X make_patchnum.pl}m;
2181
2182
2183 # "Truth in advertising" - running
2184 # make_patchnum generates 2 files.
2185 $code =~ s{^make_patchnum:.*}{
2186make_patchnum: lib/Config_git.pl
2187
2188git_version.h: lib/Config_git.pl
2189
2190perlmini\$(OBJ_EXT): git_version.h
2191
2192lib/Config_git.pl:}m;
2193 }
356fb8dd
NC
2194 # Right, now we've corrected Makefile.SH to
2195 # correctly describe how lib/Config_git.pl and
2196 # git_version.h are made, we need to fix the rest
2197
2198 # This emulates commit 2b63e250843b907e
2199 # This might duplicate the rule stating that
2200 # git_version.h depends on lib/Config_git.pl
2201 # This is harmless.
2202 $code =~ s{^(?:lib/Config_git\.pl )?git_version\.h: (.* make_patchnum\.pl.*)}
2203 {git_version.h: lib/Config_git.pl
2204
2205lib/Config_git.pl: $1}m;
2206
97897675
NC
2207 # This emulates commits 0f13ebd5d71f8177 and
2208 # and a04d4598adc57886. It ensures that
2209 # lib/Config_git.pl is built before configpm,
2210 # and that configpm is run exactly once.
2211 $code =~ s{^(\$\(.*?\) )?(\$\(CONFIGPOD\))(: .*? configpm Porting/Glossary)( lib/Config_git\.pl)?}{
2212 # If present, other files depend on $(CONFIGPOD)
2213 ($1 ? "$1: $2\n\n" : '')
2214 # Then the rule we found
2215 . $2 . $3
2216 # Add dependency if not there
2217 . ($4 ? $4 : ' lib/Config_git.pl')
2218 }me;
2219
74adbdfa
NC
2220 return $code;
2221 });
c0960282
NC
2222 }
2223 }
2224
bb723266
NC
2225 if ($major < 14) {
2226 # Commits dc0655f797469c47 and d11a62fe01f2ecb2
2227 edit_file('Makefile.SH', sub {
2228 my $code = shift;
2229 foreach my $ext (qw(Encode SDBM_File)) {
2230 next if $code =~ /\b$ext\) extra_dep=/s;
2231 $code =~ s!(\) extra_dep="\$extra_dep
2232\$this_target: .*?" ;;)
2233( esac
2234)!$1
2235 $ext) extra_dep="\$extra_dep
2236\$this_target: lib/auto/Cwd/Cwd.\$dlext" ;;
2237$2!;
2238 }
2239 return $code;
2240 });
2241 }
2242 }
2243
2244 if ($major == 7) {
2245 # Remove commits 9fec149bb652b6e9 and 5bab1179608f81d8, which add/amend
2246 # rules to automatically run regen scripts that rebuild C headers. These
2247 # cause problems because a git checkout doesn't preserve relative file
2248 # modification times, hence the regen scripts may fire. This will
2249 # obscure whether the repository had the correct generated headers
2250 # checked in.
2251 # Also, the dependency rules for running the scripts were not correct,
2252 # which could cause spurious re-builds on re-running make, and can cause
2253 # complete build failures for a parallel make.
2254 if (extract_from_file('Makefile.SH',
2255 qr/Writing it this way gives make a big hint to always run opcode\.pl before/)) {
2256 apply_commit('70c6e6715e8fec53');
2257 } elsif (extract_from_file('Makefile.SH',
2258 qr/^opcode\.h opnames\.h pp_proto\.h pp\.sym: opcode\.pl$/)) {
2259 revert_commit('9fec149bb652b6e9');
2260 }
2261 }
2262
e628fd8c
NC
2263 if ($^O eq 'aix' && $major >= 11 && $major <= 15
2264 && extract_from_file('makedef.pl', qr/^use Config/)) {
2265 edit_file('Makefile.SH', sub {
2266 # The AIX part of commit e6807d8ab22b761c
2267 # It's safe to substitute lib/Config.pm for config.sh
2268 # as lib/Config.pm depends on config.sh
2269 # If the tree is post e6807d8ab22b761c, the substitution
2270 # won't match, which is harmless.
2271 my $code = shift;
2272 $code =~ s{^(perl\.exp:.* )config\.sh(\b.*)}
2273 {$1 . '$(CONFIGPM)' . $2}me;
2274 return $code;
2275 });
2276 }
2277
bb723266
NC
2278 # There was a bug in makedepend.SH which was fixed in version 96a8704c.
2279 # Symptom was './makedepend: 1: Syntax error: Unterminated quoted string'
2280 # Remove this if you're actually bisecting a problem related to
2281 # makedepend.SH
2282 # If you do this, you may need to add in code to correct the output of older
2283 # makedepends, which don't correctly filter newer gcc output such as
2284 # <built-in>
2285 checkout_file('makedepend.SH');
2286
2287 if ($major < 4 && -f 'config.sh'
2288 && !extract_from_file('config.sh', qr/^trnl=/)) {
2289 # This seems to be necessary to avoid makedepend becoming confused,
2290 # and hanging on stdin. Seems that the code after
2291 # make shlist || ...here... is never run.
2292 edit_file('makedepend.SH', sub {
2293 my $code = shift;
2294 $code =~ s/^trnl='\$trnl'$/trnl='\\n'/m;
2295 return $code;
2296 });
2297 }
2298}
2299
2300sub patch_C {
2301 # This is ordered by $major, as it's likely that different platforms may
2302 # well want to share code.
2303
2304 if ($major == 2 && extract_from_file('perl.c', qr/^\tfclose\(e_fp\);$/)) {
2305 # need to patch perl.c to avoid calling fclose() twice on e_fp when
2306 # using -e
2307 # This diff is part of commit ab821d7fdc14a438. The second close was
2308 # introduced with perl-5.002, commit a5f75d667838e8e7
2309 # Might want a6c477ed8d4864e6 too, for the corresponding change to
2310 # pp_ctl.c (likely without this, eval will have "fun")
2311 apply_patch(<<'EOPATCH');
2312diff --git a/perl.c b/perl.c
2313index 03c4d48..3c814a2 100644
2314--- a/perl.c
2315+++ b/perl.c
2316@@ -252,6 +252,7 @@ setuid perl scripts securely.\n");
2317 #ifndef VMS /* VMS doesn't have environ array */
2318 origenviron = environ;
2319 #endif
2320+ e_tmpname = Nullch;
2321
2322 if (do_undump) {
2323
2324@@ -405,6 +406,7 @@ setuid perl scripts securely.\n");
2325 if (e_fp) {
2326 if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
2327 croak("Can't write to temp file for -e: %s", Strerror(errno));
2328+ e_fp = Nullfp;
2329 argc++,argv--;
2330 scriptname = e_tmpname;
2331 }
2332@@ -470,10 +472,10 @@ setuid perl scripts securely.\n");
2333 curcop->cop_line = 0;
2334 curstash = defstash;
2335 preprocess = FALSE;
2336- if (e_fp) {
2337- fclose(e_fp);
2338- e_fp = Nullfp;
2339+ if (e_tmpname) {
2340 (void)UNLINK(e_tmpname);
2341+ Safefree(e_tmpname);
2342+ e_tmpname = Nullch;
2343 }
2344
2345 /* now that script is parsed, we can modify record separator */
2346@@ -1369,7 +1371,7 @@ SV *sv;
2347 scriptname = xfound;
2348 }
2349
2350- origfilename = savepv(e_fp ? "-e" : scriptname);
2351+ origfilename = savepv(e_tmpname ? "-e" : scriptname);
2352 curcop->cop_filegv = gv_fetchfile(origfilename);
2353 if (strEQ(origfilename,"-"))
2354 scriptname = "";
2355
2356EOPATCH
2357 }
2358
2359 if ($major < 3 && $^O eq 'openbsd'
2360 && !extract_from_file('pp_sys.c', qr/BSD_GETPGRP/)) {
2361 # Part of commit c3293030fd1b7489
2362 apply_patch(<<'EOPATCH');
2363diff --git a/pp_sys.c b/pp_sys.c
2364index 4608a2a..f0c9d1d 100644
2365--- a/pp_sys.c
2366+++ b/pp_sys.c
2367@@ -2903,8 +2903,8 @@ PP(pp_getpgrp)
2368 pid = 0;
2369 else
2370 pid = SvIVx(POPs);
2371-#ifdef USE_BSDPGRP
2372- value = (I32)getpgrp(pid);
2373+#ifdef BSD_GETPGRP
2374+ value = (I32)BSD_GETPGRP(pid);
2375 #else
2376 if (pid != 0)
2377 DIE("POSIX getpgrp can't take an argument");
2378@@ -2933,8 +2933,8 @@ PP(pp_setpgrp)
2379 }
2380
2381 TAINT_PROPER("setpgrp");
2382-#ifdef USE_BSDPGRP
2383- SETi( setpgrp(pid, pgrp) >= 0 );
2384+#ifdef BSD_SETPGRP
2385+ SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
2386 #else
2387 if ((pgrp != 0) || (pid != 0)) {
2388 DIE("POSIX setpgrp can't take an argument");
2389EOPATCH
2390 }
2391
2392 if ($major < 4 && $^O eq 'openbsd') {
2393 my $bad;
2394 # Need changes from commit a6e633defa583ad5.
2395 # Commits c07a80fdfe3926b5 and f82b3d4130164d5f changed the same part
2396 # of perl.h
2397
2398 if (extract_from_file('perl.h',
2399 qr/^#ifdef HAS_GETPGRP2$/)) {
2400 $bad = <<'EOBAD';
2401***************
2402*** 57,71 ****
2403 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2404 #define TAINT_ENV() if (tainting) taint_env()
2405
2406! #ifdef HAS_GETPGRP2
2407! # ifndef HAS_GETPGRP
2408! # define HAS_GETPGRP
2409! # endif
2410! #endif
2411!
2412! #ifdef HAS_SETPGRP2
2413! # ifndef HAS_SETPGRP
2414! # define HAS_SETPGRP
2415! # endif
2416 #endif
2417
2418EOBAD
2419 } elsif (extract_from_file('perl.h',
2420 qr/Gack, you have one but not both of getpgrp2/)) {
2421 $bad = <<'EOBAD';
2422***************
2423*** 56,76 ****
2424 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2425 #define TAINT_ENV() if (tainting) taint_env()
2426
2427! #if defined(HAS_GETPGRP2) && defined(HAS_SETPGRP2)
2428! # define getpgrp getpgrp2
2429! # define setpgrp setpgrp2
2430! # ifndef HAS_GETPGRP
2431! # define HAS_GETPGRP
2432! # endif
2433! # ifndef HAS_SETPGRP
2434! # define HAS_SETPGRP
2435! # endif
2436! # ifndef USE_BSDPGRP
2437! # define USE_BSDPGRP
2438! # endif
2439! #else
2440! # if defined(HAS_GETPGRP2) || defined(HAS_SETPGRP2)
2441! #include "Gack, you have one but not both of getpgrp2() and setpgrp2()."
2442! # endif
2443 #endif
2444
2445EOBAD
2446 } elsif (extract_from_file('perl.h',
2447 qr/^#ifdef USE_BSDPGRP$/)) {
2448 $bad = <<'EOBAD'
2449***************
2450*** 91,116 ****
2451 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2452 #define TAINT_ENV() if (tainting) taint_env()
2453
2454! #ifdef USE_BSDPGRP
2455! # ifdef HAS_GETPGRP
2456! # define BSD_GETPGRP(pid) getpgrp((pid))
2457! # endif
2458! # ifdef HAS_SETPGRP
2459! # define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp))
2460! # endif
2461! #else
2462! # ifdef HAS_GETPGRP2
2463! # define BSD_GETPGRP(pid) getpgrp2((pid))
2464! # ifndef HAS_GETPGRP
2465! # define HAS_GETPGRP
2466! # endif
2467! # endif
2468! # ifdef HAS_SETPGRP2
2469! # define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp))
2470! # ifndef HAS_SETPGRP
2471! # define HAS_SETPGRP
2472! # endif
2473! # endif
2474 #endif
2475
2476 #ifndef _TYPES_ /* If types.h defines this it's easy. */
2477EOBAD
2478 }
2479 if ($bad) {
2480 apply_patch(<<"EOPATCH");
2481*** a/perl.h 2011-10-21 09:46:12.000000000 +0200
2482--- b/perl.h 2011-10-21 09:46:12.000000000 +0200
2483$bad--- 91,144 ----
2484 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
2485 #define TAINT_ENV() if (tainting) taint_env()
2486
2487! /* XXX All process group stuff is handled in pp_sys.c. Should these
2488! defines move there? If so, I could simplify this a lot. --AD 9/96.
2489! */
2490! /* Process group stuff changed from traditional BSD to POSIX.
2491! perlfunc.pod documents the traditional BSD-style syntax, so we'll
2492! try to preserve that, if possible.
2493! */
2494! #ifdef HAS_SETPGID
2495! # define BSD_SETPGRP(pid, pgrp) setpgid((pid), (pgrp))
2496! #else
2497! # if defined(HAS_SETPGRP) && defined(USE_BSD_SETPGRP)
2498! # define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp))
2499! # else
2500! # ifdef HAS_SETPGRP2 /* DG/UX */
2501! # define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp))
2502! # endif
2503! # endif
2504! #endif
2505! #if defined(BSD_SETPGRP) && !defined(HAS_SETPGRP)
2506! # define HAS_SETPGRP /* Well, effectively it does . . . */
2507! #endif
2508!
2509! /* getpgid isn't POSIX, but at least Solaris and Linux have it, and it makes
2510! our life easier :-) so we'll try it.
2511! */
2512! #ifdef HAS_GETPGID
2513! # define BSD_GETPGRP(pid) getpgid((pid))
2514! #else
2515! # if defined(HAS_GETPGRP) && defined(USE_BSD_GETPGRP)
2516! # define BSD_GETPGRP(pid) getpgrp((pid))
2517! # else
2518! # ifdef HAS_GETPGRP2 /* DG/UX */
2519! # define BSD_GETPGRP(pid) getpgrp2((pid))
2520! # endif
2521! # endif
2522! #endif
2523! #if defined(BSD_GETPGRP) && !defined(HAS_GETPGRP)
2524! # define HAS_GETPGRP /* Well, effectively it does . . . */
2525! #endif
2526!
2527! /* These are not exact synonyms, since setpgrp() and getpgrp() may
2528! have different behaviors, but perl.h used to define USE_BSDPGRP
2529! (prior to 5.003_05) so some extension might depend on it.
2530! */
2531! #if defined(USE_BSD_SETPGRP) || defined(USE_BSD_GETPGRP)
2532! # ifndef USE_BSDPGRP
2533! # define USE_BSDPGRP
2534! # endif
2535 #endif
2536
2537 #ifndef _TYPES_ /* If types.h defines this it's easy. */
2538EOPATCH
2539 }
2540 }
2541
8245f086
NC
2542 if ($major < 4 && $^O eq 'hpux'
2543 && extract_from_file('sv.c', qr/i = _filbuf\(/)) {
2544 apply_patch(<<'EOPATCH');
2545diff --git a/sv.c b/sv.c
2546index a1f1d60..0a806f1 100644
2547--- a/sv.c
2548+++ b/sv.c
2549@@ -2641,7 +2641,7 @@ I32 append;
2550
2551 FILE_cnt(fp) = cnt; /* deregisterize cnt and ptr */
2552 FILE_ptr(fp) = ptr;
2553- i = _filbuf(fp); /* get more characters */
2554+ i = __filbuf(fp); /* get more characters */
2555 cnt = FILE_cnt(fp);
2556 ptr = FILE_ptr(fp); /* reregisterize cnt and ptr */
2557
2558
2559EOPATCH
2560 }
2561
bb723266
NC
2562 if ($major == 4 && extract_from_file('scope.c', qr/\(SV\*\)SSPOPINT/)) {
2563 # [PATCH] 5.004_04 +MAINT_TRIAL_1 broken when sizeof(int) != sizeof(void)
2564 # Fixes a bug introduced in 161b7d1635bc830b
2565 apply_commit('9002cb76ec83ef7f');
2566 }
2567
2568 if ($major == 4 && extract_from_file('av.c', qr/AvARRAY\(av\) = 0;/)) {
2569 # Fixes a bug introduced in 1393e20655efb4bc
2570 apply_commit('e1c148c28bf3335b', 'av.c');
2571 }
2572
6626a474
NC
2573 if ($major == 4) {
2574 my $rest = extract_from_file('perl.c', qr/delimcpy(.*)/);
2575 if (defined $rest and $rest !~ /,$/) {
2576 # delimcpy added in fc36a67e8855d031, perl.c refactored to use it.
2577 # bug introduced in 2a92aaa05aa1acbf, fixed in 8490252049bf42d3
2578 # code then moved to util.c in commit 491527d0220de34e
2579 apply_patch(<<'EOPATCH');
bb723266
NC
2580diff --git a/perl.c b/perl.c
2581index 4eb69e3..54bbb00 100644
2582--- a/perl.c
2583+++ b/perl.c
2584@@ -1735,7 +1735,7 @@ SV *sv;
2585 if (len < sizeof tokenbuf)
2586 tokenbuf[len] = '\0';
2587 #else /* ! (atarist || DOSISH) */
2588- s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend
2589+ s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend,
2590 ':',
2591 &len);
2592 #endif /* ! (atarist || DOSISH) */
2593EOPATCH
6626a474 2594 }
bb723266
NC
2595 }
2596
2597 if ($major == 4 && $^O eq 'linux') {
2598 # Whilst this is fixed properly in f0784f6a4c3e45e1 which provides the
2599 # Configure probe, it's easier to back out the problematic changes made
2600 # in these previous commits:
2601 if (extract_from_file('doio.c',
2602 qr!^/\* XXX REALLY need metaconfig test \*/$!)) {
2603 revert_commit('4682965a1447ea44', 'doio.c');
2604 }
2605 if (my $token = extract_from_file('doio.c',
2606 qr!^#if (defined\(__sun(?:__)?\)) && defined\(__svr4__\) /\* XXX Need metaconfig test \*/$!)) {
2607 my $patch = `git show -R 9b599b2a63d2324d doio.c`;
2608 $patch =~ s/defined\(__sun__\)/$token/g;
2609 apply_patch($patch);
2610 }
2611 if (extract_from_file('doio.c',
2612 qr!^/\* linux \(and Solaris2\?\) uses :$!)) {
2613 revert_commit('8490252049bf42d3', 'doio.c');
2614 }
2615 if (extract_from_file('doio.c',
2616 qr/^ unsemds.buf = &semds;$/)) {
2617 revert_commit('8e591e46b4c6543e');
2618 }
2619 if (extract_from_file('doio.c',
2620 qr!^#ifdef __linux__ /\* XXX Need metaconfig test \*/$!)) {
2621 # Reverts part of commit 3e3baf6d63945cb6
2622 apply_patch(<<'EOPATCH');
2623diff --git b/doio.c a/doio.c
2624index 62b7de9..0d57425 100644
2625--- b/doio.c
2626+++ a/doio.c
2627@@ -1333,9 +1331,6 @@ SV **sp;
2628 char *a;
2629 I32 id, n, cmd, infosize, getinfo;
2630 I32 ret = -1;
2631-#ifdef __linux__ /* XXX Need metaconfig test */
2632- union semun unsemds;
2633-#endif
2634
2635 id = SvIVx(*++mark);
2636 n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
2637@@ -1364,29 +1359,11 @@ SV **sp;
2638 infosize = sizeof(struct semid_ds);
2639 else if (cmd == GETALL || cmd == SETALL)
2640 {
2641-#ifdef __linux__ /* XXX Need metaconfig test */
2642-/* linux uses :
2643- int semctl (int semid, int semnun, int cmd, union semun arg)
2644-
2645- union semun {
2646- int val;
2647- struct semid_ds *buf;
2648- ushort *array;
2649- };
2650-*/
2651- union semun semds;
2652- if (semctl(id, 0, IPC_STAT, semds) == -1)
2653-#else
2654 struct semid_ds semds;
2655 if (semctl(id, 0, IPC_STAT, &semds) == -1)
2656-#endif
2657 return -1;
2658 getinfo = (cmd == GETALL);
2659-#ifdef __linux__ /* XXX Need metaconfig test */
2660- infosize = semds.buf->sem_nsems * sizeof(short);
2661-#else
2662 infosize = semds.sem_nsems * sizeof(short);
2663-#endif
2664 /* "short" is technically wrong but much more portable
2665 than guessing about u_?short(_t)? */
2666 }
2667@@ -1429,12 +1406,7 @@ SV **sp;
2668 #endif
2669 #ifdef HAS_SEM
2670 case OP_SEMCTL:
2671-#ifdef __linux__ /* XXX Need metaconfig test */
2672- unsemds.buf = (struct semid_ds *)a;
2673- ret = semctl(id, n, cmd, unsemds);
2674-#else
2675 ret = semctl(id, n, cmd, (struct semid_ds *)a);
2676-#endif
2677 break;
2678 #endif
2679 #ifdef HAS_SHM
2680EOPATCH
2681 }
2682 # Incorrect prototype added as part of 8ac853655d9b7447, fixed as part
2683 # of commit dc45a647708b6c54, with at least one intermediate
2684 # modification. Correct prototype for gethostbyaddr has socklen_t
2685 # second. Linux has uint32_t first for getnetbyaddr.
2686 # Easiest just to remove, instead of attempting more complex patching.
2687 # Something similar may be needed on other platforms.
2688 edit_file('pp_sys.c', sub {
2689 my $code = shift;
2690 $code =~ s/^ struct hostent \*(?:PerlSock_)?gethostbyaddr\([^)]+\);$//m;
2691 $code =~ s/^ struct netent \*getnetbyaddr\([^)]+\);$//m;
2692 return $code;
2693 });
2694 }
2695
d1ac19b7
NC
2696 if ($major < 5 && $^O eq 'aix'
2697 && !extract_from_file('pp_sys.c',
2698 qr/defined\(HOST_NOT_FOUND\) && !defined\(h_errno\)/)) {
2699 # part of commit dc45a647708b6c54
2700 # Andy Dougherty's configuration patches (Config_63-01 up to 04).
2701 apply_patch(<<'EOPATCH')
2702diff --git a/pp_sys.c b/pp_sys.c
2703index c2fcb6f..efa39fb 100644
2704--- a/pp_sys.c
2705+++ b/pp_sys.c
2706@@ -54,7 +54,7 @@ extern "C" int syscall(unsigned long,...);
2707 #endif
2708 #endif
2709
2710-#ifdef HOST_NOT_FOUND
2711+#if defined(HOST_NOT_FOUND) && !defined(h_errno)
2712 extern int h_errno;
2713 #endif
2714
2715EOPATCH
2716 }
2717
df01cf53 2718 if ($major == 5
31940c07
NC
2719 && `git rev-parse HEAD` eq "22c35a8c2392967a5ba6b5370695be464bd7012c\n") {
2720 # Commit 22c35a8c2392967a is significant,
2721 # "phase 1 of somewhat major rearrangement of PERL_OBJECT stuff"
2722 # but doesn't build due to 2 simple errors. blead in this broken state
2723 # was merged to the cfgperl branch, and then these were immediately
2724 # corrected there. cfgperl (with the fixes) was merged back to blead.
2725 # The resultant rather twisty maze of commits looks like this:
2726
911bfca9 2727=begin comment
31940c07
NC
2728
2729* | | commit 137225782c183172f360c827424b9b9f8adbef0e
2730|\ \ \ Merge: 22c35a8 2a8ee23
2731| |/ / Author: Gurusamy Sarathy <gsar@cpan.org>
2732| | | Date: Fri Oct 30 17:38:36 1998 +0000
2733| | |
2734| | | integrate cfgperl tweaks into mainline
2735| | |
2736| | | p4raw-id: //depot/perl@2144
2737| | |
2738| * | commit 2a8ee23279873759693fa83eca279355db2b665c
2739| | | Author: Jarkko Hietaniemi <jhi@iki.fi>
2740| | | Date: Fri Oct 30 13:27:39 1998 +0000
2741| | |
2742| | | There can be multiple yacc/bison errors.
2743| | |
2744| | | p4raw-id: //depot/cfgperl@2143
2745| | |
2746| * | commit 93fb2ac393172fc3e2c14edb20b718309198abbc
2747| | | Author: Jarkko Hietaniemi <jhi@iki.fi>
2748| | | Date: Fri Oct 30 13:18:43 1998 +0000
2749| | |
2750| | | README.posix-bc update.
2751| | |
2752| | | p4raw-id: //depot/cfgperl@2142
2753| | |
2754| * | commit 4ec43091e8e6657cb260b5e563df30aaa154effe
2755| | | Author: Jarkko Hietaniemi <jhi@iki.fi>
2756| | | Date: Fri Oct 30 09:12:59 1998 +0000
2757| | |
2758| | | #2133 fallout.
2759| | |
2760| | | p4raw-id: //depot/cfgperl@2141
2761| | |
2762| * | commit 134ca994cfefe0f613d43505a885e4fc2100b05c
2763| |\ \ Merge: 7093112 22c35a8
2764| |/ / Author: Jarkko Hietaniemi <jhi@iki.fi>
2765|/| | Date: Fri Oct 30 08:43:18 1998 +0000
2766| | |
2767| | | Integrate from mainperl.
2768| | |
2769| | | p4raw-id: //depot/cfgperl@2140
2770| | |
2771* | | commit 22c35a8c2392967a5ba6b5370695be464bd7012c
2772| | | Author: Gurusamy Sarathy <gsar@cpan.org>
2773| | | Date: Fri Oct 30 02:51:39 1998 +0000
2774| | |
2775| | | phase 1 of somewhat major rearrangement of PERL_OBJECT stuff
2776| | | (objpp.h is gone, embed.pl now does some of that); objXSUB.h
2777| | | should soon be automated also; the global variables that
2778| | | escaped the PL_foo conversion are now reined in; renamed
2779| | | MAGIC in regcomp.h to REG_MAGIC to avoid collision with the
2780| | | type of same name; duplicated lists of pp_things in various
2781| | | places is now gone; result has only been tested on win32
2782| | |
2783| | | p4raw-id: //depot/perl@2133
2784
911bfca9
NC
2785=end comment
2786
31940c07
NC
2787=cut
2788
2789 # and completely confuses git bisect (and at least me), causing it to
2790 # the bisect run to confidently return the wrong answer, an unrelated
2791 # commit on the cfgperl branch.
2792
2793 apply_commit('4ec43091e8e6657c');
2794 }
2795
2796 if ($major == 5
df01cf53
NC
2797 && extract_from_file('pp_sys.c', qr/PERL_EFF_ACCESS_R_OK/)
2798 && !extract_from_file('pp_sys.c', qr/XXX Configure test needed for eaccess/)) {
2799 # Between 5ff3f7a4e03a6b10 and c955f1177b2e311d^
2800 # This is the meat of commit c955f1177b2e311d (without the other
2801 # indenting changes that would cause a conflict).
2802 # Without this 538 revisions won't build on (at least) Linux
2803 apply_patch(<<'EOPATCH');
2804diff --git a/pp_sys.c b/pp_sys.c
2805index d60c8dc..867dee4 100644
2806--- a/pp_sys.c
2807+++ b/pp_sys.c
2808@@ -198,9 +198,18 @@ static char zero_but_true[ZBTLEN + 1] = "0 but true";
2809 # if defined(I_SYS_SECURITY)
2810 # include <sys/security.h>
2811 # endif
2812-# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK, ACC_SELF))
2813-# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK, ACC_SELF))
2814-# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK, ACC_SELF))
2815+ /* XXX Configure test needed for eaccess */
2816+# ifdef ACC_SELF
2817+ /* HP SecureWare */
2818+# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK, ACC_SELF))
2819+# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK, ACC_SELF))
2820+# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK, ACC_SELF))
2821+# else
2822+ /* SCO */
2823+# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK))
2824+# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK))
2825+# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK))
2826+# endif
2827 #endif
2828
2829 #if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESSX) && defined(ACC_SELF)
2830EOPATCH
2831 }
2832
bb35dd48
NC
2833 if ($major == 5
2834 && extract_from_file('mg.c', qr/If we're still on top of the stack, pop us off/)
af6a5d0e 2835 && !extract_from_file('mg.c', qr/PL_savestack_ix -= popval/)) {
bb35dd48
NC
2836 # Fix up commit 455ece5e082708b1:
2837 # SSNEW() API for allocating memory on the savestack
2838 # Message-Id: <tqemtae338.fsf@puma.genscan.com>
2839 # Subject: [PATCH 5.005_51] (was: why SAVEDESTRUCTOR()...)
2840 apply_commit('3c8a44569607336e', 'mg.c');
2841 }
2842
6863570c
NC
2843 if ($major == 5) {
2844 if (extract_from_file('doop.c', qr/croak\(no_modify\);/)
2845 && extract_from_file('doop.c', qr/croak\(PL_no_modify\);/)) {
2846 # Whilst the log suggests that this would only fix 5 commits, in
2847 # practice this area of history is a complete tarpit, and git bisect
2848 # gets very confused by the skips in the middle of the back and
2849 # forth merging between //depot/perl and //depot/cfgperl
2850 apply_commit('6393042b638dafd3');
2851 }
2852
2853 # One error "fixed" with another:
2854 if (extract_from_file('pp_ctl.c',
2855 qr/\Qstatic void *docatch_body _((void *o));\E/)) {
2856 apply_commit('5b51e982882955fe');
2857 }
2858 # Which is then fixed by this:
2859 if (extract_from_file('pp_ctl.c',
2860 qr/\Qstatic void *docatch_body _((valist\E/)) {
2861 apply_commit('47aa779ee4c1a50e');
2862 }
2863
2864 if (extract_from_file('thrdvar.h', qr/PERLVARI\(Tprotect/)
2865 && !extract_from_file('embedvar.h', qr/PL_protect/)) {
2866 # Commit 312caa8e97f1c7ee didn't update embedvar.h
2867 apply_commit('e0284a306d2de082', 'embedvar.h');
2868 }
2869 }
2870
2871 if ($major == 5
2872 && extract_from_file('sv.c',
2873 qr/PerlDir_close\(IoDIRP\((?:\(IO\*\))?sv\)\);/)
2874 && !(extract_from_file('toke.c',
2875 qr/\QIoDIRP(FILTER_DATA(AvFILLp(PL_rsfp_filters))) = NULL\E/)
2876 || extract_from_file('toke.c',
2877 qr/\QIoDIRP(datasv) = (DIR*)NULL;\E/))) {
2878 # Commit 93578b34124e8a3b, //depot/perl@3298
2879 # close directory handles properly when localized,
2880 # tweaked slightly by commit 1236053a2c722e2b,
2881 # add test case for change#3298
2882 #
2883 # The fix is the last part of:
2884 #
2885 # various fixes for clean build and test on win32; configpm broken,
2886 # needed to open myconfig.SH rather than myconfig; sundry adjustments
2887 # to bytecode stuff; tweaks to DYNAMIC_ENV_FETCH code to make it
2888 # work under win32; getenv_sv() changed to getenv_len() since SVs
2889 # aren't visible in the lower echelons; remove bogus exports from
2890 # config.sym; PERL_OBJECT-ness for C++ exception support; null out
2891 # IoDIRP in filter_del() or sv_free() will attempt to close it
2892 #
2893 # The changed code is modified subsequently by commit e0c198038146b7a4
2894 apply_commit('a6c403648ecd5cc7', 'toke.c');
2895 }
2896
bb723266
NC
2897 if ($major < 6 && $^O eq 'netbsd'
2898 && !extract_from_file('unixish.h',
2899 qr/defined\(NSIG\).*defined\(__NetBSD__\)/)) {
2900 apply_patch(<<'EOPATCH')
2901diff --git a/unixish.h b/unixish.h
2902index 2a6cbcd..eab2de1 100644
2903--- a/unixish.h
2904+++ b/unixish.h
2905@@ -89,7 +89,7 @@
2906 */
2907 /* #define ALTERNATE_SHEBANG "#!" / **/
2908
2909-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
2910+#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) || defined(__NetBSD__)
2911 # include <signal.h>
2912 #endif
2913
2914EOPATCH
2915 }
2916
2917 if (($major >= 7 || $major <= 9) && $^O eq 'openbsd'
2918 && `uname -m` eq "sparc64\n"
2919 # added in 2000 by commit cb434fcc98ac25f5:
2920 && extract_from_file('regexec.c',
2921 qr!/\* No need to save/restore up to this paren \*/!)
2922 # re-indented in 2006 by commit 95b2444054382532:
2923 && extract_from_file('regexec.c', qr/^\t\tCURCUR cc;$/)) {
2924 # Need to work around a bug in (at least) OpenBSD's 4.6's sparc64 #
2925 # compiler ["gcc (GCC) 3.3.5 (propolice)"]. Between commits
2926 # 3ec562b0bffb8b8b (2002) and 1a4fad37125bac3e^ (2005) the darling thing
2927 # fails to compile any code for the statement cc.oldcc = PL_regcc;
2928 #
2929 # If you refactor the code to "fix" that, or force the issue using set
2930 # in the debugger, the stack smashing detection code fires on return
2931 # from S_regmatch(). Turns out that the compiler doesn't allocate any
2932 # (or at least enough) space for cc.
2933 #
2934 # Restore the "uninitialised" value for cc before function exit, and the
2935 # stack smashing code is placated. "Fix" 3ec562b0bffb8b8b (which
2936 # changes the size of auto variables used elsewhere in S_regmatch), and
2937 # the crash is visible back to bc517b45fdfb539b (which also changes
2938 # buffer sizes). "Unfix" 1a4fad37125bac3e and the crash is visible until
2939 # 5b47454deb66294b. Problem goes away if you compile with -O, or hack
2940 # the code as below.
2941 #
2942 # Hence this turns out to be a bug in (old) gcc. Not a security bug we
2943 # still need to fix.
2944 apply_patch(<<'EOPATCH');
2945diff --git a/regexec.c b/regexec.c
2946index 900b491..6251a0b 100644
2947--- a/regexec.c
2948+++ b/regexec.c
2949@@ -2958,7 +2958,11 @@ S_regmatch(pTHX_ regnode *prog)
2950 I,I
2951 *******************************************************************/
2952 case CURLYX: {
2953- CURCUR cc;
2954+ union {
2955+ CURCUR hack_cc;
2956+ char hack_buff[sizeof(CURCUR) + 1];
2957+ } hack;
2958+#define cc hack.hack_cc
2959 CHECKPOINT cp = PL_savestack_ix;
2960 /* No need to save/restore up to this paren */
2961 I32 parenfloor = scan->flags;
2962@@ -2983,6 +2987,7 @@ S_regmatch(pTHX_ regnode *prog)
2963 n = regmatch(PREVOPER(next)); /* start on the WHILEM */
2964 regcpblow(cp);
2965 PL_regcc = cc.oldcc;
2966+#undef cc
2967 saySAME(n);
2968 }
2969 /* NOT REACHED */
2970EOPATCH
2971}
2972
2973 if ($major < 8 && $^O eq 'openbsd'
2974 && !extract_from_file('perl.h', qr/include <unistd\.h>/)) {
2975 # This is part of commit 3f270f98f9305540, applied at a slightly
2976 # different location in perl.h, where the context is stable back to
2977 # 5.000
2978 apply_patch(<<'EOPATCH');
2979diff --git a/perl.h b/perl.h
2980index 9418b52..b8b1a7c 100644
2981--- a/perl.h
2982+++ b/perl.h
2983@@ -496,6 +496,10 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
2984 # include <sys/param.h>
2985 #endif
2986
2987+/* If this causes problems, set i_unistd=undef in the hint file. */
2988+#ifdef I_UNISTD
2989+# include <unistd.h>
2990+#endif
2991
2992 /* Use all the "standard" definitions? */
2993 #if defined(STANDARD_C) && defined(I_STDLIB)
2994EOPATCH
2995 }
2996}
2997
f2f0a0ff
NC
2998sub patch_ext {
2999 if (-f 'ext/POSIX/Makefile.PL'
3000 && extract_from_file('ext/POSIX/Makefile.PL',
3001 qr/Explicitly avoid including/)) {
3002 # commit 6695a346c41138df, which effectively reverts 170888cff5e2ffb7
3003
3004 # PERL5LIB is populated by make_ext.pl with paths to the modules we need
3005 # to run, don't override this with "../../lib" since that may not have
3006 # been populated yet in a parallel build.
3007 apply_commit('6695a346c41138df');
3008 }
3009
06cebb71
NC
3010 if (-f 'ext/Hash/Util/Makefile.PL'
3011 && extract_from_file('ext/Hash/Util/Makefile.PL',
3012 qr/\bDIR\b.*'FieldHash'/)) {
3013 # ext/Hash/Util/Makefile.PL should not recurse to FieldHash's Makefile.PL
3014 # *nix, VMS and Win32 all know how to (and have to) call the latter directly.
3015 # As is, targets in ext/Hash/Util/FieldHash get called twice, which may result
3016 # in race conditions, and certainly messes up make clean; make distclean;
3017 apply_commit('550428fe486b1888');
3018 }
3019
f2f0a0ff
NC
3020 if ($major < 8 && $^O eq 'darwin' && !-f 'ext/DynaLoader/dl_dyld.xs') {
3021 checkout_file('ext/DynaLoader/dl_dyld.xs', 'f556e5b971932902');
3022 apply_patch(<<'EOPATCH');
3023diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
3024--- a/ext/DynaLoader/dl_dyld.xs~ 2011-10-11 21:41:27.000000000 +0100
3025+++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 21:42:20.000000000 +0100
3026@@ -41,6 +41,35 @@
3027 #include "perl.h"
3028 #include "XSUB.h"
3029
3030+#ifndef pTHX
3031+# define pTHX void
3032+# define pTHX_
3033+#endif
3034+#ifndef aTHX
3035+# define aTHX
3036+# define aTHX_
3037+#endif
3038+#ifndef dTHX
3039+# define dTHXa(a) extern int Perl___notused(void)
3040+# define dTHX extern int Perl___notused(void)
3041+#endif
3042+
3043+#ifndef Perl_form_nocontext
3044+# define Perl_form_nocontext form
3045+#endif
3046+
3047+#ifndef Perl_warn_nocontext
3048+# define Perl_warn_nocontext warn
3049+#endif
3050+
3051+#ifndef PTR2IV
3052+# define PTR2IV(p) (IV)(p)
3053+#endif
3054+
3055+#ifndef get_av
3056+# define get_av perl_get_av
3057+#endif
3058+
3059 #define DL_LOADONCEONLY
3060
3061 #include "dlutils.c" /* SaveError() etc */
3062@@ -185,7 +191,7 @@
3063 CODE:
3064 DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
3065 if (flags & 0x01)
3066- Perl_warn(aTHX_ "Can't make loaded symbols global on this platform while loading %s",filename);
3067+ Perl_warn_nocontext("Can't make loaded symbols global on this platform while loading %s",filename);
3068 RETVAL = dlopen(filename, mode) ;
3069 DLDEBUG(2,PerlIO_printf(Perl_debug_log, " libref=%x\n", RETVAL));
3070 ST(0) = sv_newmortal() ;
3071EOPATCH
3072 if ($major < 4 && !extract_from_file('util.c', qr/^form/m)) {
3073 apply_patch(<<'EOPATCH');
3074diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
3075--- a/ext/DynaLoader/dl_dyld.xs~ 2011-10-11 21:56:25.000000000 +0100
3076+++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 22:00:00.000000000 +0100
3077@@ -60,6 +60,18 @@
3078 # define get_av perl_get_av
3079 #endif
3080
3081+static char *
3082+form(char *pat, ...)
3083+{
3084+ char *retval;
3085+ va_list args;
3086+ va_start(args, pat);
3087+ vasprintf(&retval, pat, &args);
3088+ va_end(args);
3089+ SAVEFREEPV(retval);
3090+ return retval;
3091+}
3092+
3093 #define DL_LOADONCEONLY
3094
3095 #include "dlutils.c" /* SaveError() etc */
3096EOPATCH
3097 }
3098 }
3099
3100 if ($major < 10) {
3101 if (!extract_from_file('ext/DB_File/DB_File.xs',
3102 qr!^#else /\* Berkeley DB Version > 2 \*/$!)) {
3103 # This DB_File.xs is really too old to patch up.
3104 # Skip DB_File, unless we're invoked with an explicit -Unoextensions
3105 if (!exists $defines{noextensions}) {
3106 $defines{noextensions} = 'DB_File';
3107 } elsif (defined $defines{noextensions}) {
3108 $defines{noextensions} .= ' DB_File';
3109 }
3110 } elsif (!extract_from_file('ext/DB_File/DB_File.xs',
3111 qr/^#ifdef AT_LEAST_DB_4_1$/)) {
3112 # This line is changed by commit 3245f0580c13b3ab
3113 my $line = extract_from_file('ext/DB_File/DB_File.xs',
3114 qr/^( status = \(?RETVAL->dbp->open\)?\(RETVAL->dbp, name, NULL, RETVAL->type, $)/);
3115 apply_patch(<<"EOPATCH");
3116diff --git a/ext/DB_File/DB_File.xs b/ext/DB_File/DB_File.xs
3117index 489ba96..fba8ded 100644
3118--- a/ext/DB_File/DB_File.xs
3119+++ b/ext/DB_File/DB_File.xs
3120\@\@ -183,4 +187,8 \@\@
3121 #endif
3122
3123+#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
3124+# define AT_LEAST_DB_4_1
3125+#endif
3126+
3127 /* map version 2 features & constants onto their version 1 equivalent */
3128
3129\@\@ -1334,7 +1419,12 \@\@ SV * sv ;
3130 #endif
3131
3132+#ifdef AT_LEAST_DB_4_1
3133+ status = (RETVAL->dbp->open)(RETVAL->dbp, NULL, name, NULL, RETVAL->type,
3134+ Flags, mode) ;
3135+#else
3136 $line
3137 Flags, mode) ;
3138+#endif
3139 /* printf("open returned %d %s\\n", status, db_strerror(status)) ; */
3140
3141EOPATCH
3142 }
3143 }
3144
3145 if ($major < 10 and -f 'ext/IPC/SysV/SysV.xs') {
3146 edit_file('ext/IPC/SysV/SysV.xs', sub {
3147 my $xs = shift;
3148 my $fixed = <<'EOFIX';
3149
3150#include <sys/types.h>
3151#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
3152#ifndef HAS_SEM
3153# include <sys/ipc.h>
3154#endif
3155# ifdef HAS_MSG
3156# include <sys/msg.h>
3157# endif
3158# ifdef HAS_SHM
3159# if defined(PERL_SCO) || defined(PERL_ISC)
3160# include <sys/sysmacros.h> /* SHMLBA */
3161# endif
3162# include <sys/shm.h>
3163# ifndef HAS_SHMAT_PROTOTYPE
3164 extern Shmat_t shmat (int, char *, int);
3165# endif
3166# if defined(HAS_SYSCONF) && defined(_SC_PAGESIZE)
3167# undef SHMLBA /* not static: determined at boot time */
3168# define SHMLBA sysconf(_SC_PAGESIZE)
3169# elif defined(HAS_GETPAGESIZE)
3170# undef SHMLBA /* not static: determined at boot time */
3171# define SHMLBA getpagesize()
3172# endif
3173# endif
3174#endif
3175EOFIX
3176 $xs =~ s!
3177#include <sys/types\.h>
3178.*
3179(#ifdef newCONSTSUB|/\* Required)!$fixed$1!ms;
3180 return $xs;
3181 });
3182 }
3183}
3184
df14fc13
NC
3185sub apply_fixups {
3186 my $fixups = shift;
3187 return unless $fixups;
3188 foreach my $file (@$fixups) {
3189 my $fh = open_or_die($file);
3190 my $line = <$fh>;
3191 close_or_die($fh);
3192 if ($line =~ /^#!perl\b/) {
3193 system $^X, $file
3194 and die_255("$^X $file failed: \$!=$!, \$?=$?");
3195 } elsif ($line =~ /^#!(\/\S+)/) {
3196 system $file
3197 and die_255("$file failed: \$!=$!, \$?=$?");
3198 } else {
3199 if (my ($target, $action, $pattern)
3200 = $line =~ m#^(\S+) ([=!])~ /(.*)/#) {
3201 if (length $pattern) {
3202 next unless -f $target;
3203 if ($action eq '=') {
3204 next unless extract_from_file($target, $pattern);
3205 } else {
3206 next if extract_from_file($target, $pattern);
3207 }
3208 } else {
3209 # Avoid the special case meaning of the empty pattern,
3210 # and instead use this to simply test for the file being
3211 # present or absent
3212 if ($action eq '=') {
3213 next unless -f $target;
3214 } else {
3215 next if -f $target;
3216 }
3217 }
3218 }
3219 system_or_die("patch -p1 <$file");
3220 }
3221 }
3222}
3223
9a999a97
NC
3224# Local variables:
3225# cperl-indent-level: 4
3226# indent-tabs-mode: nil
3227# End:
3228#
3229# ex: set ts=8 sts=4 sw=4 et: