Subject: [bug#30469] [PATCH 1/1] build: Require Guile >= 2.0.14.

From: Ludovic Courtès <[email-masked]>
Date: Thu, 15 Feb 2018 16:29:57 +0100

* README, configure.ac, doc/guix.texi (Requirements): Increase minimum
Guile version from 2.0.9 to 2.0.14.
* config-daemon.ac: Remove use of 'GUIX_CHECK_UNBUFFERED_CBIP'.
* m4/guix.m4 (GUIX_CHECK_UNBUFFERED_CBIP): Remove.
* guix/build/download.scm (current-http-proxy): Remove.
* guix/build/syscalls.scm (%libc-errno-pointer, errno): Remove.
(syscall->procedure): Use #:return-errno unconditionally.
* guix/hash.scm (open-sha256-input-port)[unbuffered]: Remove outdated
comment.
* guix/http-client.scm (when-guile<=2.0.5-or-otherwise-broken): Remove.
<top level>: Remove 'when-guile<=2.0.5-or-otherwise-broken' block.
* guix/scripts/substitute.scm (fetch): Remove 'guile-version>?'
conditional.
* tests/hash.scm (supports-unbuffered-cbip?): Remove.
<top level>: Remove 'test-skip' call.
---
 README                      |   2 +-
 config-daemon.ac            |   5 --
 configure.ac                |   2 +-
 doc/guix.texi               |   2 +-
 guix/build/download.scm     |  10 +--
 guix/build/syscalls.scm     |  48 +-------------
 guix/hash.scm               |   3 +-
 guix/http-client.scm        | 154 +-------------------------------------------
 guix/scripts/substitute.scm |  18 ++----
 m4/guix.m4                  |  17 -----
 tests/hash.scm              |  11 +---
 11 files changed, 14 insertions(+), 258 deletions(-)

diff --git a/README b/README
index d96a43bbe..6d1a10ad5 100644
--- a/README
+++ b/README
@@ -20,7 +20,7 @@ Guix is based on the [[https://nixos.org/nix/][Nix]] package manager.
 
 GNU Guix currently depends on the following packages:
 
-  - [[https://gnu.org/software/guile/][GNU Guile 2.2.x or 2.0.x]], version 2.0.9 or later
+  - [[https://gnu.org/software/guile/][GNU Guile 2.2.x or 2.0.x]], version 2.0.14 or later
   - [[https://gnupg.org/][GNU libgcrypt]]
   - [[https://www.gnu.org/software/make/][GNU Make]]
   - [[https://www.gnutls.org][GnuTLS]] compiled with guile support enabled.
diff --git a/config-daemon.ac b/config-daemon.ac
index 80d84cbdb..524b10b30 100644
--- a/config-daemon.ac
+++ b/config-daemon.ac
@@ -132,11 +132,6 @@ if test "x$guix_build_daemon" = "xyes"; then
   AC_DEFINE_UNQUOTED([GUIX_SUBSTITUTE_URLS], ["$guix_substitute_urls"],
     [Default list of substitute URLs used by 'guix-daemon'.])
 
-  dnl Check whether the 'offload' build hook can be built (uses
-  dnl 'restore-file-set', which requires unbuffered custom binary input
-  dnl ports from Guile >= 2.0.10.)
-  GUIX_CHECK_UNBUFFERED_CBIP
-
   dnl Check for Guile-SSH, which is required by 'guix offload'.
   GUIX_CHECK_GUILE_SSH
 
diff --git a/configure.ac b/configure.ac
index 398846f64..d533c160e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -98,7 +98,7 @@ if test "x$GUILD" = "x"; then
 fi
 
 if test "x$GUILE_EFFECTIVE_VERSION" = "x2.0"; then
-  PKG_CHECK_MODULES([GUILE], [guile-2.0 >= 2.0.9])
+  PKG_CHECK_MODULES([GUILE], [guile-2.0 >= 2.0.14])
 fi
 
 dnl Installation directories for .scm and .go files.
diff --git a/doc/guix.texi b/doc/guix.texi
index 7ed39ff13..9227e0e83 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -601,7 +601,7 @@ in the Guix source tree for additional details.
 GNU Guix depends on the following packages:
 
 @itemize
-@item @url{http://gnu.org/software/guile/, GNU Guile}, version 2.0.9 or
+@item @url{http://gnu.org/software/guile/, GNU Guile}, version 2.0.14 or
 later, including 2.2.x;
 @item @url{http://gnupg.org/, GNU libgcrypt};
 @item
diff --git a/guix/build/download.scm b/guix/build/download.scm
index 1b630a9d6..315a3554e 100644
--- a/guix/build/download.scm
+++ b/guix/build/download.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2015 Mark H Weaver <[email-masked]>
 ;;; Copyright © 2017 Tobias Geerinckx-Rice <[email-masked]>
 ;;;
@@ -321,14 +321,6 @@ host name without trailing dot."
    ((uri? uri-or-string) uri-or-string)
    (else (error "Invalid URI" uri-or-string))))
 
-(define current-http-proxy
-  ;; XXX: Add a dummy definition for Guile < 2.0.10; this is used in
-  ;; 'open-socket-for-uri'.
-  (or (and=> (module-variable (resolve-interface '(web client))
-                              'current-http-proxy)
-             variable-ref)
-      (const #f)))
-
 (define* (open-socket-for-uri uri-or-string #:key timeout)
   "Return an open input/output port for a connection to URI.  When TIMEOUT is
 not #f, it must be a (possibly inexact) number denoting the maximum duration
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 0cb630cfb..25726b885 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2015 David Thompson <[email-masked]>
 ;;; Copyright © 2015 Mark H Weaver <[email-masked]>
 ;;; Copyright © 2017 Mathieu Othacehe <[email-masked]>
@@ -350,39 +350,6 @@ expansion-time error is raised if FIELD does not exist in TYPE."
 ;;; FFI.
 ;;;
 
-(define %libc-errno-pointer
-  ;; Glibc's 'errno' pointer, for use with Guile < 2.0.12.
-  (let ((errno-loc (false-if-exception
-                    (dynamic-func "__errno_location" (dynamic-link)))))
-    (and errno-loc
-         (let ((proc (pointer->procedure '* errno-loc '())))
-           (proc)))))
-
-(define errno                                     ;for Guile < 2.0.12
-  (if %libc-errno-pointer
-      (let ((bv (pointer->bytevector %libc-errno-pointer (sizeof int))))
-        (lambda ()
-          "Return the current errno."
-          ;; XXX: We assume that nothing changes 'errno' while we're doing all this.
-          ;; In particular, that means that no async must be running here.
-
-          ;; Use one of the fixed-size native-ref procedures because they are
-          ;; optimized down to a single VM instruction, which reduces the risk
-          ;; that we fiddle with 'errno' (needed on Guile 2.0.5, libc 2.11.)
-          (let-syntax ((ref (lambda (s)
-                              (syntax-case s ()
-                                ((_ bv)
-                                 (case (sizeof int)
-                                   ((4)
-                                    #'(bytevector-s32-native-ref bv 0))
-                                   ((8)
-                                    #'(bytevector-s64-native-ref bv 0))
-                                   (else
-                                    (error "unsupported 'int' size"
-                                           (sizeof int)))))))))
-            (ref bv))))
-      (lambda () 0)))
-
 (define (call-with-restart-on-EINTR thunk)
   (let loop ()
     (catch 'system-error
@@ -406,17 +373,8 @@ the returned procedure is called."
     (lambda ()
       (let ((ptr (dynamic-func name (dynamic-link))))
         ;; The #:return-errno? facility was introduced in Guile 2.0.12.
-        ;; Support older versions of Guile by catching 'wrong-number-of-args'.
-        (catch 'wrong-number-of-args
-          (lambda ()
-            (pointer->procedure return-type ptr argument-types
-                                #:return-errno? #t))
-          (lambda (key . rest)
-            (let ((proc (pointer->procedure return-type ptr argument-types)))
-              (lambda args
-                (let ((result (apply proc args))
-                      (err    (errno)))
-                  (values result err))))))))
+        (pointer->procedure return-type ptr argument-types
+                            #:return-errno? #t)))
     (lambda args
       (lambda _
         (error (format #f "~a: syscall->procedure failed: ~s"
diff --git a/guix/hash.scm b/guix/hash.scm
index 44e447258..773b9d477 100644
--- a/guix/hash.scm
+++ b/guix/hash.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018 Ludovic Courtès <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -159,7 +159,6 @@ data read from PORT.  The thunk always returns the same value."
 
   (define (unbuffered port)
     ;; Guile <= 2.0.9 does not support 'setvbuf' on custom binary input ports.
-    ;; If you get a wrong-type-arg error here, the fix is to upgrade Guile.  :-)
     (setvbuf port _IONBF)
     port)
 
diff --git a/guix/http-client.scm b/guix/http-client.scm
index bab31875d..e8a2a23fc 100644
--- a/guix/http-client.scm
+++ b/guix/http-client.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2015 Mark H Weaver <[email-masked]>
 ;;; Copyright © 2012, 2015 Free Software Foundation, Inc.
 ;;; Copyright © 2017 Tobias Geerinckx-Rice <[email-masked]>
@@ -69,158 +69,6 @@
   (reason http-get-error-reason))                 ; string

-(define-syntax when-guile<=2.0.5-or-otherwise-broken
-  (lambda (s)
-    (syntax-case s ()
-      ((_ body ...)
-       ;; Always emit BODY, regardless of VERSION, because sometimes this code
-       ;; might be compiled with a recent Guile and run with 2.0.5---e.g.,
-       ;; when using "guix pull".
-       #'(begin body ...)))))
-
-(when-guile<=2.0.5-or-otherwise-broken
- ;; Backport of Guile commits 312e79f8 ("Add HTTP Chunked Encoding support to
- ;; web modules."), 00d3ecf2 ("http: Do not buffer HTTP chunks."), and 53b8d5f
- ;; ("web: Gracefully handle premature EOF when reading chunk header.")
-
- (use-modules (ice-9 rdelim))
-
- (define %web-http
-   (resolve-module '(web http)))
-
- ;; Chunked Responses
- (define (read-chunk-header port)
-   "Read a chunk header from PORT and return the size in bytes of the
- upcoming chunk."
-   (match (read-line port)
-     ((? eof-object?)
-      ;; Connection closed prematurely: there's nothing left to read.
-      0)
-     (str
-      (let ((extension-start (string-index str
-                                           (lambda (c)
-                                             (or (char=? c #\;)
-                                                 (char=? c #\return))))))
-        (string->number (if extension-start       ; unnecessary?
-                            (substring str 0 extension-start)
-                            str)
-                        16)))))
-
- (define* (make-chunked-input-port port #:key (keep-alive? #f))
-   "Returns a new port which translates HTTP chunked transfer encoded
-data from PORT into a non-encoded format. Returns eof when it has
-read the final chunk from PORT. This does not necessarily mean
-that there is no more data on PORT. When the returned port is
-closed it will also close PORT, unless the KEEP-ALIVE? is true."
-   (define (close)
-     (unless keep-alive?
-       (close-port port)))
-
-   (define chunk-size 0)     ;size of the current chunk
-   (define remaining 0)      ;number of bytes left from the current chunk
-   (define finished? #f)     ;did we get all the chunks?
-
-   (define (read! bv idx to-read)
-     (define (loop to-read num-read)
-       (cond ((or finished? (zero? to-read))
-              num-read)
-             ((zero? remaining)                    ;get a new chunk
-              (let ((size (read-chunk-header port)))
-                (set! chunk-size size)
-                (set! remaining size)
-                (if (zero? size)
-                    (begin
-                      (set! finished? #t)
-                      num-read)
-                    (loop to-read num-read))))
-             (else                           ;read from the current chunk
-              (let* ((ask-for (min to-read remaining))
-                     (read    (get-bytevector-n! port bv (+ idx num-read)
-                                                 ask-for)))
-                (if (eof-object? read)
-                    (begin                         ;premature termination
-                      (set! finished? #t)
-                      num-read)
-                    (let ((left (- remaining read)))
-                      (set! remaining left)
-                      (when (zero? left)
-                        ;; We're done with this chunk; read CR and LF.
-                        (get-u8 port) (get-u8 port))
-                      (loop (- to-read read)
-                            (+ num-read read))))))))
-     (loop to-read 0))
-
-   (make-custom-binary-input-port "chunked input port" read! #f #f close))
-
- ;; Chunked encoding support in Guile <= 2.0.11 would load whole chunks in
- ;; memory---see <http://bugs.gnu.org/19939>.
- (when (module-variable %web-http 'read-chunk-body)
-   (module-set! %web-http 'make-chunked-input-port make-chunked-input-port))
-
- (define (make-delimited-input-port port len keep-alive?)
-   "Return an input port that reads from PORT, and makes sure that
-exactly LEN bytes are available from PORT.  Closing the returned port
-closes PORT, unless KEEP-ALIVE? is true."
-   (define bytes-read 0)
-
-   (define (fail)
-     ((@@ (web response) bad-response)
-      "EOF while reading response body: ~a bytes of ~a"
-      bytes-read len))
-
-   (define (read! bv start count)
-     ;; Read at most LEN bytes in total.  HTTP/1.1 doesn't say what to do
-     ;; when a server provides more than the Content-Length, but it seems
-     ;; wise to just stop reading at LEN.
-     (let ((count (min count (- len bytes-read))))
-       (let loop ((ret (get-bytevector-n! port bv start count)))
-         (cond ((eof-object? ret)
-                (if (= bytes-read len)
-                    0                              ; EOF
-                    (fail)))
-               ((and (zero? ret) (> count 0))
-                ;; Do not return zero since zero means EOF, so try again.
-                (loop (get-bytevector-n! port bv start count)))
-               (else
-                (set! bytes-read (+ bytes-read ret))
-                ret)))))
-
-   (define close
-     (and (not keep-alive?)
-          (lambda ()
-            (close-port port))))
-
-   (make-custom-binary-input-port "delimited input port" read! #f #f close))
-
- (define (read-header-line port)
-   "Read an HTTP header line and return it without its final CRLF or LF.
-Raise a 'bad-header' exception if the line does not end in CRLF or LF,
-or if EOF is reached."
-   (match (%read-line port)
-     (((? string? line) . #\newline)
-      ;; '%read-line' does not consider #\return a delimiter; so if it's
-      ;; there, remove it.  We are more tolerant than the RFC in that we
-      ;; tolerate LF-only endings.
-      (if (string-suffix? "\r" line)
-          (string-drop-right line 1)
-          line))
-     ((line . _)                                ;EOF or missing delimiter
-      ((@@ (web http) bad-header) 'read-header-line line))))
-
- (unless (guile-version>? "2.0.11")
-   ;; Guile <= 2.0.9 had a bug whereby 'response-body-port' would read more
-   ;; than what 'content-length' says.  See Guile commit 802a25b.
-   ;; Guile <= 2.0.11 had a bug whereby the 'close' method of the response
-   ;; body port would fail with wrong-arg-num.  See Guile commit 5a10e41.
-   (module-set! (resolve-module '(web response))
-                'make-delimited-input-port make-delimited-input-port)
-
-   ;; Guile <= 2.0.11 was affected by <http://bugs.gnu.org/22273>.  See Guile
-   ;; commit 4c7732c.
-   (when (module-variable %web-http 'read-line*)
-     (module-set! %web-http 'read-line* read-header-line))))
-
-
 (define* (http-fetch uri #:key port (text? #f) (buffered? #t)
                      keep-alive? (verify-certificate? #t)
                      (headers '((user-agent . "GNU Guile"))))
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index 2fd2bf810..8e1119fb4 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <[email-masked]>
 ;;; Copyright © 2014 Nikita Karetnikov <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -212,15 +212,7 @@ provide."
            (begin
              (warning (G_ "while fetching ~a: server is somewhat slow~%")
                       (uri->string uri))
-             (warning (G_ "try `--no-substitutes' if the problem persists~%"))
-
-             ;; Before Guile v2.0.9-39-gfe51c7b, EINTR was reported to the user,
-             ;; and thus PORT had to be closed and re-opened.  This is not the
-             ;; case afterward.
-             (unless (or (guile-version>? "2.0.9")
-                         (version>? (version) "2.0.9.39"))
-               (when port
-                 (close-connection port))))
+             (warning (G_ "try `--no-substitutes' if the problem persists~%")))
            (begin
              (when (or (not port) (port-closed? port))
                (set! port (guix:open-connection-for-uri
@@ -571,10 +563,8 @@ initial connection on which HTTP requests are sent."
       ;; XXX: Do our own caching to work around inefficiencies when
       ;; communicating over TLS: <http://bugs.gnu.org/22966>.
       (let-values (((buffer get) (open-bytevector-output-port)))
-        ;; On Guile > 2.0.9, inherit the HTTP proxying property from P.
-        (when (module-variable (resolve-interface '(web http))
-                               'http-proxy-port?)
-          (set-http-proxy-port?! buffer (http-proxy-port? p)))
+        ;; Inherit the HTTP proxying property from P.
+        (set-http-proxy-port?! buffer (http-proxy-port? p))
 
         (for-each (cut write-request <> buffer)
                   (at-most 1000 requests))
diff --git a/m4/guix.m4 b/m4/guix.m4
index 721285b01..8e174e92e 100644
--- a/m4/guix.m4
+++ b/m4/guix.m4
@@ -136,23 +136,6 @@ AC_DEFUN([GUIX_ASSERT_GUILE_FEATURES], [
   done
 ])
 
-dnl GUIX_CHECK_UNBUFFERED_CBIP
-dnl
-dnl Check whether 'setbvuf' works on custom binary input ports (CBIPs), as is
-dnl the case starting with Guile 2.0.10.
-AC_DEFUN([GUIX_CHECK_UNBUFFERED_CBIP], [
-  AC_CACHE_CHECK([whether Guile's custom binary input ports support 'setvbuf'],
-    [ac_cv_guix_cbips_support_setvbuf],
-    [if "$GUILE" -c "(use-modules (rnrs io ports))			\
-       (let ((p (make-custom-binary-input-port \"cbip\" pk #f #f #f)))	\
-         (setvbuf p _IONBF))" >&5 2>&1
-     then
-       ac_cv_guix_cbips_support_setvbuf=yes
-     else
-       ac_cv_guix_cbips_support_setvbuf=no
-     fi])
-])
-
 dnl GUIX_ASSERT_SYNTAX_OBJECT_EQUAL
 dnl
 dnl Guile 2.2.1 was a brown-paper-bag release where 'equal?' wouldn't work
diff --git a/tests/hash.scm b/tests/hash.scm
index b189e435c..b4cf2b61d 100644
--- a/tests/hash.scm
+++ b/tests/hash.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2017 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2013, 2014, 2017, 2018 Ludovic Courtès <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -37,13 +37,6 @@
   (base16-string->bytevector
    "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"))
 
-(define (supports-unbuffered-cbip?)
-  "Return #t if unbuffered custom binary input ports (CBIPs) are supported.
-In Guile <= 2.0.9, CBIPs were always fully buffered, so the
-'open-sha256-input-port' does not work there."
-  (false-if-exception
-   (setvbuf (make-custom-binary-input-port "foo" pk #f #f #f) _IONBF)))
-
 
 (test-begin "hash")
 
@@ -77,8 +70,6 @@ In Guile <= 2.0.9, CBIPs were always fully buffered, so the
     (equal? (sha256 contents)
             (call-with-input-file file port-sha256))))
 
-(test-skip (if (supports-unbuffered-cbip?) 0 4))
-
 (test-equal "open-sha256-input-port, empty"
   `("" ,%empty-sha256)
   (let-values (((port get)
-- 
2.16.1