<pre style='margin:0'>
Herby Gillot (herbygillot) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/0435fe55210208e7d4f4ec6b4954a7d746a1a971">https://github.com/macports/macports-ports/commit/0435fe55210208e7d4f4ec6b4954a7d746a1a971</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 0435fe55210208e7d4f4ec6b4954a7d746a1a971
</span>Author: Sergey Fedorov <vital.had@gmail.com>
AuthorDate: Fri Feb 9 07:04:45 2024 +0800

<span style='display:block; white-space:pre;color:#404040;'>    go: unbreak i386
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Fixes: https://trac.macports.org/ticket/69160
</span><span style='display:block; white-space:pre;color:#404040;'>    Fixes: https://trac.macports.org/ticket/64169
</span>---
 lang/go/Portfile                               |  75 +++-
 lang/go/files/patch-1.11.13-for-10.6-i386.diff | 540 +++++++++++++++++++++++++
 2 files changed, 595 insertions(+), 20 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/go/Portfile b/lang/go/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 0de05ea5669..df171f6d194 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/lang/go/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/go/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -15,26 +15,41 @@ epoch               3
</span> # tested the candidate version using the `go-devel` port, to verify how it
 # builds against current and older versions of macOS.
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# Go 1.22 does not build on macOS 10.12 and older
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Go 1.22 does not build on macOS 10.12 and older.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 1.14.x is the last branch to support i386 on macOS.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# However past 1.11.x everything is broken.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# FIXME: consider implementing support for PowerPC.
</span> if {${os.platform} eq "darwin" && ${os.major} < 17} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    version         1.17.13
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    set unsupported_macos true
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    revision        0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${build_arch} eq "i386"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        version     1.11.13
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        revision    0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set unsupported_macos_386 true
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set unsupported_macos false
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        version     1.17.13
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        revision    0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set unsupported_macos true
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set unsupported_macos_386 false
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> } else {
     version         1.22.0
     set unsupported_macos false
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    set unsupported_macos_386 false
</span>     revision        0
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-set legacy_build    false
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> # Subport for Go Unstable Version
 subport ${name}-devel {
     version         1.22.0
     revision        0
     epoch           1
<span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set legacy_build false
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${os.platform} eq "darwin" \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    && (${os.major} < 11 || ${configure.build_arch} eq "i386")} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set legacy_build    true
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set legacy_build    false
</span> }
 
 homepage            https://go.dev
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -82,7 +97,17 @@ if {$subport eq "${name}-devel"} {
</span> } else {
     # Go (RELEASE)
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {${unsupported_macos}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${unsupported_macos_386}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # 1.11
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        checksums   ${go_src_dist} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    rmd160  19d71fb4c196bd5bb03cab40cc99b35f312aaefc \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    sha256  5032095fd3f641cafcce164f551e5ae873785ce7b07ca7c143aecd18f7ba4076 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    size    21114296
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        notes-append "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            Please note: Go 1.22 does not build on macOS 10.6 and older, so Go ${version} has been installed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif {${unsupported_macos}} {
</span>         # 1.17
         checksums   ${go_src_dist} \
                     rmd160  6d8a13da5112ee67bb886eca0fec77ffaab27a5f \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -159,6 +184,7 @@ build.env           GOROOT=${GOROOT} \
</span>                     GOOS=darwin \
                     GOROOT_FINAL=${GOROOT_FINAL} \
                     CC=${configure.cc}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> # Set build.jobs to -1 to disable MacPorts from adding the -j flag for
 # parallel builds, since the build.cmd contains "make".
 build.jobs          -1
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -168,12 +194,12 @@ if {${os.platform} eq "darwin" && ${os.major} <= ${legacysupport.newest_darwin_r
</span>     # since go doesn't use the standard CFLAGS/CXXFLAGS.
     # We need to patch the build system and set up env variables manually.
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {[vercmp ${version} < 1.19]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # Older compilers don't support the -Wno-nullability-completeness flag and if
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # that's the case, they won't need it anyway, so just patch it out.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # Upstream no longer uses the flag as of 1.19beta1.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # https://github.com/golang/go/commit/bf19163a545c3117ab3c309a691f32a42cf29efd
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    patchfiles-append   patch-cgo-drop-no-nullability-completeness.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[vercmp ${version} < 1.19] && !${legacy_build}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Older compilers don't support the -Wno-nullability-completeness flag and if
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # that's the case, they won't need it anyway, so just patch it out.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Upstream no longer uses the flag as of 1.19beta1.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # https://github.com/golang/go/commit/bf19163a545c3117ab3c309a691f32a42cf29efd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        patchfiles-append   patch-cgo-drop-no-nullability-completeness.diff
</span>     }
 
     # Fix building with the -x flag ("show all commands as they are executed"),
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -214,9 +240,13 @@ if {${os.platform} eq "darwin" && ${os.major} <= ${legacysupport.newest_darwin_r
</span>     }]
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {${os.platform} eq "darwin" && ${os.major} eq 10} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # The branch https://github.com/catap/go/tree/macos-10.6
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    patchfiles-append   patch-macOS-10.6.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${os.platform} eq "darwin" && ${os.major} == 10} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${configure.build_arch} eq "x86_64"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # The branch https://github.com/catap/go/tree/macos-10.6
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        patchfiles-append   patch-macOS-10.6.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif {${configure.build_arch} eq "i386"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        patchfiles-append   patch-1.11.13-for-10.6-i386.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> }
 
 use_parallel_build  no
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -237,7 +267,7 @@ if {${configure.build_arch} eq "arm64"} {
</span>             "${extract.cmd} ${extract.pre_args} ${distpath}/${go_armbin_dist} ${extract.post_args}"
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-} elseif {(${configure.build_arch} eq "x86_64" && ${os.major} >= 21) || !${legacy_build}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} elseif {${configure.build_arch} eq "x86_64" && (${os.major} >= 21 || !${legacy_build})} {
</span> 
     # Use a temporary installation of the binary AMD64 Go distribution to
     # build Go for AMD64 on macOS 12 since go-1.4 fails to build
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -255,7 +285,9 @@ if {${configure.build_arch} eq "arm64"} {
</span> 
 } else {
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    build.env-append        GOROOT_BOOTSTRAP=${prefix}/lib/go-1.4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # https://trac.macports.org/ticket/69160
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    build.env-append        GOROOT_BOOTSTRAP=${prefix}/lib/go-1.4 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            GOHOSTARCH=${GOARCH}
</span> 
     depends_build-append    port:go-1.4
 }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -300,10 +332,13 @@ destroot {
</span>         LICENSE \
         README.md \
         PATENTS \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        SECURITY.md \
</span>         VERSION \
         ${docdir}
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {!${legacy_build}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        xinstall -m 0644 -W ${worksrcpath} SECURITY.md ${docdir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>     copy {*}[glob -directory ${worksrcpath}/doc *] ${docdir}
 
     if { [ file exists ${worksrcpath}/go.env ] } {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/go/files/patch-1.11.13-for-10.6-i386.diff b/lang/go/files/patch-1.11.13-for-10.6-i386.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..ba0289dc291
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/go/files/patch-1.11.13-for-10.6-i386.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,540 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From f417aba5a5c66b6eef35658dc0079fa0f5ee59a7 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Sergey Fedorov <vital.had@gmail.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Fri, 9 Feb 2024 19:27:50 +0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] Fix 1.11.13 for 10.6 i386
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/cmd/link/internal/ld/lib.go     |   3 -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/crypto/x509/root_cgo_darwin.go  | 278 +++++++++++-----------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/crypto/x509/root_darwin.go      |  18 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/internal/poll/fd_unix.go        |  13 ++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/runtime/crash_cgo_test.go       |  13 ++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/syscall/zerrors_darwin_386.go   |   2 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/syscall/zerrors_darwin_amd64.go |   2 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 7 files changed, 141 insertions(+), 188 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/cmd/link/internal/ld/lib.go src/cmd/link/internal/ld/lib.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f2c61b60c0..6ada49c392 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/cmd/link/internal/ld/lib.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/cmd/link/internal/ld/lib.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1091,9 +1091,6 @@ func (ctxt *Link) hostlink() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if ctxt.DynlinkingGo() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   argv = append(argv, "-Wl,-flat_namespace")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if ctxt.BuildMode == BuildModeExe && !ctxt.Arch.InFamily(sys.ARM64) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  argv = append(argv, "-Wl,-no_pie")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   case objabi.Hopenbsd:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           argv = append(argv, "-Wl,-nopie")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   case objabi.Hwindows:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/crypto/x509/root_cgo_darwin.go src/crypto/x509/root_cgo_darwin.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 1c20f26acb..86b6831e33 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/crypto/x509/root_cgo_darwin.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/crypto/x509/root_cgo_darwin.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -7,7 +7,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ package x509
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#cgo CFLAGS: -mmacosx-version-min=10.10 -D__MAC_OS_X_VERSION_MAX_ALLOWED=101300
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cgo LDFLAGS: -framework CoreFoundation -framework Security
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <errno.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -16,135 +16,59 @@ package x509
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <CoreFoundation/CoreFoundation.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <Security/Security.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static Boolean isSSLPolicy(SecPolicyRef policyRef) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (!policyRef) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFDictionaryRef properties = SecPolicyCopyProperties(policyRef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (properties == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  Boolean isSSL = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFTypeRef value = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          isSSL = CFEqual(value, kSecPolicyAppleSSL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFRelease(properties);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  return isSSL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// for a certificate in the user or admin domain, combining usage constraints
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// for the SSL SecTrustSettingsPolicy, ignoring SecTrustSettingsKeyUsage and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// kSecTrustSettingsAllowedError.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// https://developer.apple.com/documentation/security/1400261-sectrustsettingscopytrustsetting
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static SInt32 sslTrustSettingsResult(SecCertificateRef cert) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFArrayRef trustSettings = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  OSStatus err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainUser, &trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // According to Apple's SecTrustServer.c, "user trust settings overrule admin trust settings",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // but the rules of the override are unclear. Let's assume admin trust settings are applicable
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // if and only if user trust settings fail to load or are NULL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (err != errSecSuccess || trustSettings == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (trustSettings != NULL) CFRelease(trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainAdmin, &trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // > no trust settings [...] means "this certificate must be verified to a known trusted certificate”
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (err != errSecSuccess || trustSettings == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (trustSettings != NULL) CFRelease(trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return kSecTrustSettingsResultUnspecified;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// FetchPEMRoots_MountainLion is the version of FetchPEMRoots from Go 1.6
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// which still works on OS X 10.8 (Mountain Lion).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// It lacks support for admin & user cert domains.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// See golang.org/issue/16473
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int FetchPEMRoots_MountainLion(CFDataRef *pemRoots) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (pemRoots == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // > An empty trust settings array means "always trust this certificate” with an
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // > overall trust setting for the certificate of kSecTrustSettingsResultTrustRoot.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (CFArrayGetCount(trustSettings) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          CFRelease(trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return kSecTrustSettingsResultTrustRoot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CFArrayRef certs = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  OSStatus err = SecTrustCopyAnchorCertificates(&certs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (err != noErr) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // kSecTrustSettingsResult is defined as CFSTR("kSecTrustSettingsResult"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // but the Go linker's internal linking mode can't handle CFSTR relocations.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // Create our own dynamic string instead and release it below.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFStringRef _kSecTrustSettingsResult = CFStringCreateWithCString(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          NULL, "kSecTrustSettingsResult", kCFStringEncodingUTF8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFStringRef _kSecTrustSettingsPolicy = CFStringCreateWithCString(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          NULL, "kSecTrustSettingsPolicy", kCFStringEncodingUTF8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFStringRef _kSecTrustSettingsPolicyString = CFStringCreateWithCString(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          NULL, "kSecTrustSettingsPolicyString", kCFStringEncodingUTF8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFIndex m; SInt32 result = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  for (m = 0; m < CFArrayGetCount(trustSettings); m++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, m);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          // First, check if this trust setting applies to our policy. We assume
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          // only one will. The docs suggest that there might be multiple applying
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          // but don't explain how to combine them.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          SecPolicyRef policyRef;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsPolicy, (const void**)&policyRef)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  if (!isSSLPolicy(policyRef)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int i, ncerts = CFArrayGetCount(certs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (i = 0; i < ncerts; i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          CFDataRef data = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (cert == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // Restricted to a hostname, not a root.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // Once we support weak imports via cgo we should prefer that, and fall back to this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // for older systems.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (err != noErr) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          CFNumberRef cfNum;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsResult, (const void**)&cfNum)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // > If the value of the kSecTrustSettingsResult component is not
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // > kSecTrustSettingsResultUnspecified for a usage constraints dictionary that has
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // > no constraints, the default value kSecTrustSettingsResultTrustRoot is assumed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  result = kSecTrustSettingsResultTrustRoot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (data != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  CFRelease(data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // If trust settings are present, but none of them match the policy...
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // the docs don't tell us what to do.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  //
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // "Trust settings for a given use apply if any of the dictionaries in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // certificate’s trust settings array satisfies the specified use." suggests
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // that it's as if there were no trust settings at all, so we should probably
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // fallback to the admin trust settings. TODO.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (result == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          result = kSecTrustSettingsResultUnspecified;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFRelease(_kSecTrustSettingsPolicy);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFRelease(_kSecTrustSettingsPolicyString);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFRelease(_kSecTrustSettingsResult);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFRelease(trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CFRelease(certs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  *pemRoots = combinedData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// isRootCertificate reports whether Subject and Issuer match.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, errRef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (*errRef != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, errRef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (*errRef != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          CFRelease(subjectName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  Boolean equal = CFEqual(subjectName, issuerName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFRelease(subjectName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  CFRelease(issuerName);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  return equal;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// useOldCode reports whether the running machine is OS X 10.8 Mountain Lion
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// or older. We only support Mountain Lion and higher, but we'll at least try our
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// best on older machines and continue to use the old code path.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// See golang.org/issue/16473
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int useOldCode() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  char str[256];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t size = sizeof(str);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  memset(str, 0, size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  sysctlbyname("kern.osrelease", str, &size, NULL, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // OS X 10.8 is osrelease "12.*", 10.7 is 11.*, 10.6 is 10.*.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // We never supported things before that.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return memcmp(str, "12.", 3) == 0 || memcmp(str, "11.", 3) == 0 || memcmp(str, "10.", 3) == 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// FetchPEMRoots fetches the system's list of trusted X.509 root certificates
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// for the kSecTrustSettingsPolicy SSL.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// FetchPEMRoots fetches the system's list of trusted X.509 root certificates.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ //
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // certificates of the system. On failure, the function returns -1.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -152,15 +76,11 @@ static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ //
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // Note: The CFDataRef returned in pemRoots and untrustedPemRoots must
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // be released (using CFRelease) after we've consumed its content.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if (debugDarwinRoots) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          printf("crypto/x509: kSecTrustSettingsResultInvalid = %d\n", kSecTrustSettingsResultInvalid);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          printf("crypto/x509: kSecTrustSettingsResultTrustRoot = %d\n", kSecTrustSettingsResultTrustRoot);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          printf("crypto/x509: kSecTrustSettingsResultTrustAsRoot = %d\n", kSecTrustSettingsResultTrustAsRoot);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          printf("crypto/x509: kSecTrustSettingsResultDeny = %d\n", kSecTrustSettingsResultDeny);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          printf("crypto/x509: kSecTrustSettingsResultUnspecified = %d\n", kSecTrustSettingsResultUnspecified);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (useOldCode()) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          return FetchPEMRoots_MountainLion(pemRoots);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // Get certificates from all domains, not just System, this lets
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -174,6 +94,11 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // kSecTrustSettingsResult is defined as CFSTR("kSecTrustSettingsResult"),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // but the Go linker's internal linking mode can't handle CFSTR relocations.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // Create our own dynamic string instead and release it below.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CFStringRef policy = CFStringCreateWithCString(NULL, "kSecTrustSettingsResult", kCFStringEncodingUTF8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   CFMutableDataRef combinedUntrustedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   for (i = 0; i < numDomains; i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -187,81 +112,85 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           CFIndex numCerts = CFArrayGetCount(certs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           for (j = 0; j < numCerts; j++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   CFDataRef data = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  CFErrorRef errRef = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   CFArrayRef trustSettings = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (cert == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  SInt32 result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  if (domains[i] == kSecTrustSettingsDomainSystem) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // We only want trusted certs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  int untrusted = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  int trustAsRoot = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  int trustRoot = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if (i == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          trustAsRoot = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          int k;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          CFIndex m;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           // Certs found in the system domain are always trusted. If the user
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           // configures "Never Trust" on such a cert, it will also be found in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           // admin or user domain, causing it to be added to untrustedPemRoots. The
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           // Go code will then clean this up.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          result = kSecTrustSettingsResultTrustRoot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          result = sslTrustSettingsResult(cert);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          if (debugDarwinRoots) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  CFErrorRef errRef = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  CFStringRef summary = SecCertificateCopyShortDescription(NULL, cert, &errRef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  if (errRef != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          printf("crypto/x509: SecCertificateCopyShortDescription failed\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          CFRelease(errRef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          // Trust may be stored in any of the domains. According to Apple's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          // SecTrustServer.c, "user trust settings overrule admin trust settings",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          // so take the last trust settings array we find.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          // Skip the system domain since it is always trusted.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          for (k = i; k < numDomains; k++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  CFArrayRef domainTrustSettings = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  err = SecTrustSettingsCopyTrustSettings(cert, domains[k], &domainTrustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  if (err == errSecSuccess && domainTrustSettings != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          if (trustSettings) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  CFRelease(trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          trustSettings = domainTrustSettings;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  CFIndex length = CFStringGetLength(summary);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  char *buffer = malloc(maxSize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  if (CFStringGetCString(summary, buffer, maxSize, kCFStringEncodingUTF8)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                          printf("crypto/x509: %s returned %d\n", buffer, (int)result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  free(buffer);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  CFRelease(summary);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  CFMutableDataRef appendTo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // > Note the distinction between the results kSecTrustSettingsResultTrustRoot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // > and kSecTrustSettingsResultTrustAsRoot: The former can only be applied to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // > root (self-signed) certificates; the latter can only be applied to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  // > non-root certificates.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  if (result == kSecTrustSettingsResultTrustRoot) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          CFErrorRef errRef = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          if (!isRootCertificate(cert, &errRef) || errRef != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  if (errRef != NULL) CFRelease(errRef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          if (trustSettings == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  // "this certificate must be verified to a known trusted certificate"; aka not a root.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                   continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          appendTo = combinedData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  } else if (result == kSecTrustSettingsResultTrustAsRoot) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          CFErrorRef errRef = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          if (isRootCertificate(cert, &errRef) || errRef != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  if (errRef != NULL) CFRelease(errRef);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                  continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          for (m = 0; m < CFArrayGetCount(trustSettings); m++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  CFNumberRef cfNum;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, m);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  if (CFDictionaryGetValueIfPresent(tSetting, policy, (const void**)&cfNum)){
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          SInt32 result = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          // TODO: The rest of the dictionary specifies conditions for evaluation.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          if (result == kSecTrustSettingsResultDeny) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  untrusted = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          } else if (result == kSecTrustSettingsResultTrustAsRoot) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  trustAsRoot = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          } else if (result == kSecTrustSettingsResultTrustRoot) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                  trustRoot = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          appendTo = combinedData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  } else if (result == kSecTrustSettingsResultDeny) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          appendTo = combinedUntrustedData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  } else if (result == kSecTrustSettingsResultUnspecified) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                          continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          CFRelease(trustSettings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // Once we support weak imports via cgo we should prefer that, and fall back to this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // for older systems.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (err != noErr) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (data != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          if (!trustRoot && !trustAsRoot) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                  untrusted = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          CFMutableDataRef appendTo = untrusted ? combinedUntrustedData : combinedData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           CFDataAppendBytes(appendTo, CFDataGetBytePtr(data), CFDataGetLength(data));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           CFRelease(data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           CFRelease(certs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CFRelease(policy);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   *pemRoots = combinedData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   *untrustedPemRoots = combinedUntrustedData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -278,8 +207,9 @@ func loadSystemRoots() (*CertPool, error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   var data C.CFDataRef = 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   var untrustedData C.CFDataRef = 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  err := C.FetchPEMRoots(&data, &untrustedData, C.bool(debugDarwinRoots))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  err := C.FetchPEMRoots(&data, &untrustedData)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if err == -1 {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // TODO: better error message
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/crypto/x509/root_darwin.go src/crypto/x509/root_darwin.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b0460527b1..8de5af9cd5 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/crypto/x509/root_darwin.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/crypto/x509/root_darwin.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -22,7 +22,7 @@ import (
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   "sync"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-var debugDarwinRoots = strings.Contains(os.Getenv("GODEBUG"), "x509roots=1")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++var debugExecDarwinRoots = strings.Contains(os.Getenv("GODEBUG"), "x509roots=1")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return nil, nil
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -58,7 +58,7 @@ func execSecurityRoots() (*CertPool, error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if err != nil {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return nil, err
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if debugDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if debugExecDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           fmt.Printf("crypto/x509: %d certs have a trust policy\n", len(hasPolicy))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -66,8 +66,8 @@ func execSecurityRoots() (*CertPool, error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   u, err := user.Current()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if err != nil {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if debugDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  fmt.Printf("crypto/x509: can't get user home directory: %v\n", err)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if debugExecDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  fmt.Printf(fmt.Sprintf("crypto/x509: get current user: %v", err))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           keychains = append(keychains,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -146,7 +146,7 @@ func execSecurityRoots() (*CertPool, error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   close(verifyCh)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   wg.Wait()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if debugDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if debugExecDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           fmt.Printf("crypto/x509: ran security verify-cert %d times\n", numVerified)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -199,16 +199,16 @@ func verifyCertWithSystem(cert *Certificate) bool {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   cmd := exec.Command("/usr/bin/security", "verify-cert", "-p", "ssl", "-c", f.Name(), "-l", "-L")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   var stderr bytes.Buffer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if debugDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if debugExecDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           cmd.Stderr = &stderr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if err := cmd.Run(); err != nil {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          if debugDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if debugExecDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   fmt.Printf("crypto/x509: verify-cert rejected %s: %q\n", cert.Subject, bytes.TrimSpace(stderr.Bytes()))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return false
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  if debugDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if debugExecDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           fmt.Printf("crypto/x509: verify-cert approved %s\n", cert.Subject)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   return true
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -241,7 +241,7 @@ func getCertsWithTrustPolicy() (map[string]bool, error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   // Rather than match on English substrings that are probably
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   // localized on macOS, just interpret any failure to mean that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   // there are no trust settings.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                  if debugDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if debugExecDarwinRoots {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                           fmt.Printf("crypto/x509: exec %q: %v, %s\n", cmd.Args, err, stderr.Bytes())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   return nil
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/internal/poll/fd_unix.go src/internal/poll/fd_unix.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b311049ad7..7306b937fc 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/internal/poll/fd_unix.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/internal/poll/fd_unix.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -453,6 +453,19 @@ var tryDupCloexec = int32(1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ func DupCloseOnExec(fd int) (int, string, error) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if atomic.LoadInt32(&tryDupCloexec) == 1 {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // On OS X 10.6 and below (but we only support
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // >= 10.6), F_DUPFD_CLOEXEC is unsupported
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // and fcntl there falls back (undocumented)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // to doing an ioctl instead, returning EBADF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // in this case because fd is not of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // expected device fd type. Treat it as
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // EINVAL instead, so we fall back to the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // normal dup path.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // TODO: only do this on 10.6 if we can detect 10.6
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // cheaply.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  e1 = syscall.EINVAL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           switch e1 {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           case 0:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   return int(r0), "", nil
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/runtime/crash_cgo_test.go src/runtime/crash_cgo_test.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 6da8341e84..e6f61081aa 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/runtime/crash_cgo_test.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/runtime/crash_cgo_test.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -90,6 +90,19 @@ func TestCgoExternalThreadSIGPROF(t *testing.T) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   case "plan9", "windows":
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           t.Skipf("no pthreads on %s", runtime.GOOS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  case "darwin":
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if runtime.GOARCH != "arm" && runtime.GOARCH != "arm64" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // static constructor needs external linking, but we don't support
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // external linking on OS X 10.6.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  out, err := exec.Command("uname", "-r").Output()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if err != nil {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          t.Fatalf("uname -r failed: %v", err)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  // OS X 10.6 == Darwin 10.x
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  if strings.HasPrefix(string(out), "10.") {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                          t.Skipf("no external linking on OS X 10.6")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if runtime.GOARCH == "ppc64" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           // TODO(austin) External linking not implemented on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           // ppc64 (issue #8912)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/syscall/zerrors_darwin_386.go src/syscall/zerrors_darwin_386.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 776aecbf33..1c11de8124 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/syscall/zerrors_darwin_386.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/syscall/zerrors_darwin_386.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -232,7 +232,7 @@ const (
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_ALLOCATECONTIG                  = 0x2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_CHKCLEAN                        = 0x29
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_DUPFD                           = 0x0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  F_DUPFD_CLOEXEC                   = 0x43
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  F_DUPFD_CLOEXEC                   = 0x0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_FLUSH_DATA                      = 0x28
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_FREEZE_FS                       = 0x35
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_FULLFSYNC                       = 0x33
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/syscall/zerrors_darwin_amd64.go src/syscall/zerrors_darwin_amd64.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 58799fbde7..8d35537a0b 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/syscall/zerrors_darwin_amd64.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/syscall/zerrors_darwin_amd64.go
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -232,7 +232,7 @@ const (
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_ALLOCATECONTIG                  = 0x2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_CHKCLEAN                        = 0x29
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_DUPFD                           = 0x0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  F_DUPFD_CLOEXEC                   = 0x43
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  F_DUPFD_CLOEXEC                   = 0x0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_FLUSH_DATA                      = 0x28
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_FREEZE_FS                       = 0x35
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   F_FULLFSYNC                       = 0x33
</span></pre><pre style='margin:0'>

</pre>