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