From dd9afe64b51aefb38e35e39b1f5ac8196cb70d21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
Date: Fri, 10 May 2013 01:14:25 +0200
Subject: [PATCH] download: Fix premature socket close on TLS connections.

This would manifest when downloading a large file such as the Bazaar
tarball, leading to an "Error in the pull function" GnuTLS exception.

* guix/build/download.scm (add-weak-reference): New procedure.
  (tls-wrap): Add (add-weak-reference record port).
---
 guix/build/download.scm | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/guix/build/download.scm b/guix/build/download.scm
index 6c2e8235d07..53e6b2363c6 100644
--- a/guix/build/download.scm
+++ b/guix/build/download.scm
@@ -101,6 +101,12 @@ (define (ftp-fetch uri file)
 (module-autoload! (current-module)
                   '(gnutls) '(make-session connection-end/client))
 
+(define add-weak-reference
+  (let ((table (make-weak-key-hash-table)))
+    (lambda (from to)
+      "Hold a weak reference from FROM to TO."
+      (hashq-set! table from to))))
+
 (define (tls-wrap port)
   "Return PORT wrapped in a TLS connection."
   (define (log level str)
@@ -117,7 +123,13 @@ (define (log level str)
     ;;(set-log-procedure! log)
 
     (handshake session)
-    (session-record-port session)))
+    (let ((record (session-record-port session)))
+      ;; Since we use `fileno' above, the file descriptor behind PORT would be
+      ;; closed when PORT is GC'd.  If we used `port->fdes', it would instead
+      ;; never be closed.  So we use `fileno', but keep a weak reference to
+      ;; PORT, so the file descriptor gets closed when RECORD is GC'd.
+      (add-weak-reference record port)
+      record)))
 
 (define (open-connection-for-uri uri)
   "Return an open input/output port for a connection to URI.
-- 
GitLab