+ if ($major == 4) {
+ my $rest = extract_from_file('perl.c', qr/delimcpy(.*)/);
+ if (defined $rest and $rest !~ /,$/) {
+ # delimcpy added in fc36a67e8855d031, perl.c refactored to use it.
+ # bug introduced in 2a92aaa05aa1acbf, fixed in 8490252049bf42d3
+ # code then moved to util.c in commit 491527d0220de34e
+ apply_patch(<<'EOPATCH');
+diff --git a/perl.c b/perl.c
+index 4eb69e3..54bbb00 100644
+--- a/perl.c
++++ b/perl.c
+@@ -1735,7 +1735,7 @@ SV *sv;
+ if (len < sizeof tokenbuf)
+ tokenbuf[len] = '\0';
+ #else /* ! (atarist || DOSISH) */
+- s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend
++ s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend,
+ ':',
+ &len);
+ #endif /* ! (atarist || DOSISH) */
+EOPATCH
+ }
+ }
+
+ if ($major == 4 && $^O eq 'linux') {
+ # Whilst this is fixed properly in f0784f6a4c3e45e1 which provides the
+ # Configure probe, it's easier to back out the problematic changes made
+ # in these previous commits:
+ if (extract_from_file('doio.c',
+ qr!^/\* XXX REALLY need metaconfig test \*/$!)) {
+ revert_commit('4682965a1447ea44', 'doio.c');
+ }
+ if (my $token = extract_from_file('doio.c',
+ qr!^#if (defined\(__sun(?:__)?\)) && defined\(__svr4__\) /\* XXX Need metaconfig test \*/$!)) {
+ my $patch = `git show -R 9b599b2a63d2324d doio.c`;
+ $patch =~ s/defined\(__sun__\)/$token/g;
+ apply_patch($patch);
+ }
+ if (extract_from_file('doio.c',
+ qr!^/\* linux \(and Solaris2\?\) uses :$!)) {
+ revert_commit('8490252049bf42d3', 'doio.c');
+ }
+ if (extract_from_file('doio.c',
+ qr/^ unsemds.buf = &semds;$/)) {
+ revert_commit('8e591e46b4c6543e');
+ }
+ if (extract_from_file('doio.c',
+ qr!^#ifdef __linux__ /\* XXX Need metaconfig test \*/$!)) {
+ # Reverts part of commit 3e3baf6d63945cb6
+ apply_patch(<<'EOPATCH');
+diff --git b/doio.c a/doio.c
+index 62b7de9..0d57425 100644
+--- b/doio.c
++++ a/doio.c
+@@ -1333,9 +1331,6 @@ SV **sp;
+ char *a;
+ I32 id, n, cmd, infosize, getinfo;
+ I32 ret = -1;
+-#ifdef __linux__ /* XXX Need metaconfig test */
+- union semun unsemds;
+-#endif
+
+ id = SvIVx(*++mark);
+ n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
+@@ -1364,29 +1359,11 @@ SV **sp;
+ infosize = sizeof(struct semid_ds);
+ else if (cmd == GETALL || cmd == SETALL)
+ {
+-#ifdef __linux__ /* XXX Need metaconfig test */
+-/* linux uses :
+- int semctl (int semid, int semnun, int cmd, union semun arg)
+-
+- union semun {
+- int val;
+- struct semid_ds *buf;
+- ushort *array;
+- };
+-*/
+- union semun semds;
+- if (semctl(id, 0, IPC_STAT, semds) == -1)
+-#else
+ struct semid_ds semds;
+ if (semctl(id, 0, IPC_STAT, &semds) == -1)
+-#endif
+ return -1;
+ getinfo = (cmd == GETALL);
+-#ifdef __linux__ /* XXX Need metaconfig test */
+- infosize = semds.buf->sem_nsems * sizeof(short);
+-#else
+ infosize = semds.sem_nsems * sizeof(short);
+-#endif
+ /* "short" is technically wrong but much more portable
+ than guessing about u_?short(_t)? */
+ }
+@@ -1429,12 +1406,7 @@ SV **sp;
+ #endif
+ #ifdef HAS_SEM
+ case OP_SEMCTL:
+-#ifdef __linux__ /* XXX Need metaconfig test */
+- unsemds.buf = (struct semid_ds *)a;
+- ret = semctl(id, n, cmd, unsemds);
+-#else
+ ret = semctl(id, n, cmd, (struct semid_ds *)a);
+-#endif
+ break;
+ #endif
+ #ifdef HAS_SHM
+EOPATCH
+ }
+ # Incorrect prototype added as part of 8ac853655d9b7447, fixed as part
+ # of commit dc45a647708b6c54, with at least one intermediate
+ # modification. Correct prototype for gethostbyaddr has socklen_t
+ # second. Linux has uint32_t first for getnetbyaddr.
+ # Easiest just to remove, instead of attempting more complex patching.
+ # Something similar may be needed on other platforms.
+ edit_file('pp_sys.c', sub {
+ my $code = shift;
+ $code =~ s/^ struct hostent \*(?:PerlSock_)?gethostbyaddr\([^)]+\);$//m;
+ $code =~ s/^ struct netent \*getnetbyaddr\([^)]+\);$//m;
+ return $code;
+ });
+ }
+
+ if ($major < 5 && $^O eq 'aix'
+ && !extract_from_file('pp_sys.c',
+ qr/defined\(HOST_NOT_FOUND\) && !defined\(h_errno\)/)) {
+ # part of commit dc45a647708b6c54
+ # Andy Dougherty's configuration patches (Config_63-01 up to 04).
+ apply_patch(<<'EOPATCH')
+diff --git a/pp_sys.c b/pp_sys.c
+index c2fcb6f..efa39fb 100644
+--- a/pp_sys.c
++++ b/pp_sys.c
+@@ -54,7 +54,7 @@ extern "C" int syscall(unsigned long,...);
+ #endif
+ #endif
+
+-#ifdef HOST_NOT_FOUND
++#if defined(HOST_NOT_FOUND) && !defined(h_errno)
+ extern int h_errno;
+ #endif
+
+EOPATCH
+ }
+
+ if ($major == 5
+ && `git rev-parse HEAD` eq "22c35a8c2392967a5ba6b5370695be464bd7012c\n") {
+ # Commit 22c35a8c2392967a is significant,
+ # "phase 1 of somewhat major rearrangement of PERL_OBJECT stuff"
+ # but doesn't build due to 2 simple errors. blead in this broken state
+ # was merged to the cfgperl branch, and then these were immediately
+ # corrected there. cfgperl (with the fixes) was merged back to blead.
+ # The resultant rather twisty maze of commits looks like this:
+
+=begin comment
+
+* | | commit 137225782c183172f360c827424b9b9f8adbef0e
+|\ \ \ Merge: 22c35a8 2a8ee23
+| |/ / Author: Gurusamy Sarathy <gsar@cpan.org>
+| | | Date: Fri Oct 30 17:38:36 1998 +0000
+| | |
+| | | integrate cfgperl tweaks into mainline
+| | |
+| | | p4raw-id: //depot/perl@2144
+| | |
+| * | commit 2a8ee23279873759693fa83eca279355db2b665c
+| | | Author: Jarkko Hietaniemi <jhi@iki.fi>
+| | | Date: Fri Oct 30 13:27:39 1998 +0000
+| | |
+| | | There can be multiple yacc/bison errors.
+| | |
+| | | p4raw-id: //depot/cfgperl@2143
+| | |
+| * | commit 93fb2ac393172fc3e2c14edb20b718309198abbc
+| | | Author: Jarkko Hietaniemi <jhi@iki.fi>
+| | | Date: Fri Oct 30 13:18:43 1998 +0000
+| | |
+| | | README.posix-bc update.
+| | |
+| | | p4raw-id: //depot/cfgperl@2142
+| | |
+| * | commit 4ec43091e8e6657cb260b5e563df30aaa154effe
+| | | Author: Jarkko Hietaniemi <jhi@iki.fi>
+| | | Date: Fri Oct 30 09:12:59 1998 +0000
+| | |
+| | | #2133 fallout.
+| | |
+| | | p4raw-id: //depot/cfgperl@2141
+| | |
+| * | commit 134ca994cfefe0f613d43505a885e4fc2100b05c
+| |\ \ Merge: 7093112 22c35a8
+| |/ / Author: Jarkko Hietaniemi <jhi@iki.fi>
+|/| | Date: Fri Oct 30 08:43:18 1998 +0000
+| | |
+| | | Integrate from mainperl.
+| | |
+| | | p4raw-id: //depot/cfgperl@2140
+| | |
+* | | commit 22c35a8c2392967a5ba6b5370695be464bd7012c
+| | | Author: Gurusamy Sarathy <gsar@cpan.org>
+| | | Date: Fri Oct 30 02:51:39 1998 +0000
+| | |
+| | | phase 1 of somewhat major rearrangement of PERL_OBJECT stuff
+| | | (objpp.h is gone, embed.pl now does some of that); objXSUB.h
+| | | should soon be automated also; the global variables that
+| | | escaped the PL_foo conversion are now reined in; renamed
+| | | MAGIC in regcomp.h to REG_MAGIC to avoid collision with the
+| | | type of same name; duplicated lists of pp_things in various
+| | | places is now gone; result has only been tested on win32
+| | |
+| | | p4raw-id: //depot/perl@2133
+
+=end comment
+
+=cut
+
+ # and completely confuses git bisect (and at least me), causing it to
+ # the bisect run to confidently return the wrong answer, an unrelated
+ # commit on the cfgperl branch.
+
+ apply_commit('4ec43091e8e6657c');
+ }
+
+ if ($major == 5
+ && extract_from_file('pp_sys.c', qr/PERL_EFF_ACCESS_R_OK/)
+ && !extract_from_file('pp_sys.c', qr/XXX Configure test needed for eaccess/)) {
+ # Between 5ff3f7a4e03a6b10 and c955f1177b2e311d^
+ # This is the meat of commit c955f1177b2e311d (without the other
+ # indenting changes that would cause a conflict).
+ # Without this 538 revisions won't build on (at least) Linux
+ apply_patch(<<'EOPATCH');
+diff --git a/pp_sys.c b/pp_sys.c
+index d60c8dc..867dee4 100644
+--- a/pp_sys.c
++++ b/pp_sys.c
+@@ -198,9 +198,18 @@ static char zero_but_true[ZBTLEN + 1] = "0 but true";
+ # if defined(I_SYS_SECURITY)
+ # include <sys/security.h>
+ # endif
+-# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK, ACC_SELF))
+-# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK, ACC_SELF))
+-# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK, ACC_SELF))
++ /* XXX Configure test needed for eaccess */
++# ifdef ACC_SELF
++ /* HP SecureWare */
++# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK, ACC_SELF))
++# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK, ACC_SELF))
++# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK, ACC_SELF))
++# else
++ /* SCO */
++# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK))
++# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK))
++# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK))
++# endif
+ #endif
+
+ #if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESSX) && defined(ACC_SELF)
+EOPATCH
+ }
+
+ if ($major == 5
+ && extract_from_file('mg.c', qr/If we're still on top of the stack, pop us off/)
+ && !extract_from_file('mg.c', qr/PL_savestack_ix -= popval/)) {
+ # Fix up commit 455ece5e082708b1:
+ # SSNEW() API for allocating memory on the savestack
+ # Message-Id: <tqemtae338.fsf@puma.genscan.com>
+ # Subject: [PATCH 5.005_51] (was: why SAVEDESTRUCTOR()...)
+ apply_commit('3c8a44569607336e', 'mg.c');
+ }
+
+ if ($major == 5) {
+ if (extract_from_file('doop.c', qr/croak\(no_modify\);/)
+ && extract_from_file('doop.c', qr/croak\(PL_no_modify\);/)) {
+ # Whilst the log suggests that this would only fix 5 commits, in
+ # practice this area of history is a complete tarpit, and git bisect
+ # gets very confused by the skips in the middle of the back and
+ # forth merging between //depot/perl and //depot/cfgperl
+ apply_commit('6393042b638dafd3');
+ }
+
+ # One error "fixed" with another:
+ if (extract_from_file('pp_ctl.c',
+ qr/\Qstatic void *docatch_body _((void *o));\E/)) {
+ apply_commit('5b51e982882955fe');
+ }
+ # Which is then fixed by this:
+ if (extract_from_file('pp_ctl.c',
+ qr/\Qstatic void *docatch_body _((valist\E/)) {
+ apply_commit('47aa779ee4c1a50e');
+ }
+
+ if (extract_from_file('thrdvar.h', qr/PERLVARI\(Tprotect/)
+ && !extract_from_file('embedvar.h', qr/PL_protect/)) {
+ # Commit 312caa8e97f1c7ee didn't update embedvar.h
+ apply_commit('e0284a306d2de082', 'embedvar.h');
+ }
+ }
+
+ if ($major == 5
+ && extract_from_file('sv.c',
+ qr/PerlDir_close\(IoDIRP\((?:\(IO\*\))?sv\)\);/)
+ && !(extract_from_file('toke.c',
+ qr/\QIoDIRP(FILTER_DATA(AvFILLp(PL_rsfp_filters))) = NULL\E/)
+ || extract_from_file('toke.c',
+ qr/\QIoDIRP(datasv) = (DIR*)NULL;\E/))) {
+ # Commit 93578b34124e8a3b, //depot/perl@3298
+ # close directory handles properly when localized,
+ # tweaked slightly by commit 1236053a2c722e2b,
+ # add test case for change#3298
+ #
+ # The fix is the last part of:
+ #
+ # various fixes for clean build and test on win32; configpm broken,
+ # needed to open myconfig.SH rather than myconfig; sundry adjustments
+ # to bytecode stuff; tweaks to DYNAMIC_ENV_FETCH code to make it
+ # work under win32; getenv_sv() changed to getenv_len() since SVs
+ # aren't visible in the lower echelons; remove bogus exports from
+ # config.sym; PERL_OBJECT-ness for C++ exception support; null out
+ # IoDIRP in filter_del() or sv_free() will attempt to close it
+ #
+ # The changed code is modified subsequently by commit e0c198038146b7a4
+ apply_commit('a6c403648ecd5cc7', 'toke.c');
+ }
+
+ if ($major < 6 && $^O eq 'netbsd'
+ && !extract_from_file('unixish.h',
+ qr/defined\(NSIG\).*defined\(__NetBSD__\)/)) {
+ apply_patch(<<'EOPATCH')
+diff --git a/unixish.h b/unixish.h
+index 2a6cbcd..eab2de1 100644
+--- a/unixish.h
++++ b/unixish.h
+@@ -89,7 +89,7 @@
+ */
+ /* #define ALTERNATE_SHEBANG "#!" / **/
+
+-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
++#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) || defined(__NetBSD__)
+ # include <signal.h>
+ #endif
+
+EOPATCH
+ }
+
+ if (($major >= 7 || $major <= 9) && $^O eq 'openbsd'
+ && `uname -m` eq "sparc64\n"
+ # added in 2000 by commit cb434fcc98ac25f5:
+ && extract_from_file('regexec.c',
+ qr!/\* No need to save/restore up to this paren \*/!)
+ # re-indented in 2006 by commit 95b2444054382532:
+ && extract_from_file('regexec.c', qr/^\t\tCURCUR cc;$/)) {
+ # Need to work around a bug in (at least) OpenBSD's 4.6's sparc64 #
+ # compiler ["gcc (GCC) 3.3.5 (propolice)"]. Between commits
+ # 3ec562b0bffb8b8b (2002) and 1a4fad37125bac3e^ (2005) the darling thing
+ # fails to compile any code for the statement cc.oldcc = PL_regcc;
+ #
+ # If you refactor the code to "fix" that, or force the issue using set
+ # in the debugger, the stack smashing detection code fires on return
+ # from S_regmatch(). Turns out that the compiler doesn't allocate any
+ # (or at least enough) space for cc.
+ #
+ # Restore the "uninitialised" value for cc before function exit, and the
+ # stack smashing code is placated. "Fix" 3ec562b0bffb8b8b (which
+ # changes the size of auto variables used elsewhere in S_regmatch), and
+ # the crash is visible back to bc517b45fdfb539b (which also changes
+ # buffer sizes). "Unfix" 1a4fad37125bac3e and the crash is visible until
+ # 5b47454deb66294b. Problem goes away if you compile with -O, or hack
+ # the code as below.
+ #
+ # Hence this turns out to be a bug in (old) gcc. Not a security bug we
+ # still need to fix.
+ apply_patch(<<'EOPATCH');
+diff --git a/regexec.c b/regexec.c
+index 900b491..6251a0b 100644
+--- a/regexec.c
++++ b/regexec.c
+@@ -2958,7 +2958,11 @@ S_regmatch(pTHX_ regnode *prog)
+ I,I
+ *******************************************************************/
+ case CURLYX: {
+- CURCUR cc;
++ union {
++ CURCUR hack_cc;
++ char hack_buff[sizeof(CURCUR) + 1];
++ } hack;
++#define cc hack.hack_cc
+ CHECKPOINT cp = PL_savestack_ix;
+ /* No need to save/restore up to this paren */
+ I32 parenfloor = scan->flags;
+@@ -2983,6 +2987,7 @@ S_regmatch(pTHX_ regnode *prog)
+ n = regmatch(PREVOPER(next)); /* start on the WHILEM */
+ regcpblow(cp);
+ PL_regcc = cc.oldcc;
++#undef cc
+ saySAME(n);
+ }
+ /* NOT REACHED */
+EOPATCH