gnu: gnutls: Patch the Guile bindings for EINTR/EAGAIN handling.

* gnu/packages/patches/gnutls-guile-eintr-eagain.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/tls.scm (gnutls)[source]: Use it.
This commit is contained in:
Ludovic Courtès 2021-07-31 15:44:58 +02:00
parent 2c0013916e
commit 69dde4e354
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
3 changed files with 59 additions and 1 deletions

View file

@ -1144,6 +1144,7 @@ dist_patch_DATA = \
%D%/packages/patches/gnupg-default-pinentry.patch \
%D%/packages/patches/gnutls-skip-trust-store-test.patch \
%D%/packages/patches/gnutls-cross.patch \
%D%/packages/patches/gnutls-guile-eintr-eagain.patch \
%D%/packages/patches/gobject-introspection-absolute-shlib-path.patch \
%D%/packages/patches/gobject-introspection-cc.patch \
%D%/packages/patches/gobject-introspection-girepository.patch \

View file

@ -0,0 +1,56 @@
Fixes <https://issues.guix.gnu.org/47867>.
This fix was merged upstream
in <https://gitlab.com/gnutls/gnutls/-/merge_requests/1417> and will
be in GnuTLS 3.7.3. Upstream commit:
commit 110e2172dbef1fbdf7399dab1e80780847b61c0c
Author: Ludovic Courtès <ludo@gnu.org>
Date: Sat Apr 24 22:02:14 2021 +0200
guile: Writes to record ports handle EAGAIN/EINTR transparently.
diff --git a/guile/src/core.c b/guile/src/core.c
index a13670fc7b..0926dc8a97 100644
--- a/guile/src/core.c
+++ b/guile/src/core.c
@@ -985,7 +985,10 @@ write_to_session_record_port (SCM port, const void *data, size_t size)
c_result = gnutls_record_send (c_session, (char *) data + c_sent,
size - c_sent);
if (EXPECT_FALSE (c_result < 0))
- scm_gnutls_error (c_result, FUNC_NAME);
+ {
+ if (c_result != GNUTLS_E_AGAIN && c_result != GNUTLS_E_INTERRUPTED)
+ scm_gnutls_error (c_result, FUNC_NAME);
+ }
else
c_sent += c_result;
}
@@ -1069,7 +1072,8 @@ read_from_session_record_port (SCM port, SCM dst, size_t start, size_t count)
#undef FUNC_NAME
/* Return the file descriptor that backs PORT. This function is called upon a
- blocking read--i.e., 'read_from_session_record_port' returned -1. */
+ blocking read--i.e., 'read_from_session_record_port' or
+ 'write_to_session_record_port' returned -1. */
static int
session_record_port_fd (SCM port)
{
@@ -1097,7 +1101,16 @@ write_to_session_record_port (SCM port, SCM src, size_t start, size_t count)
c_session = scm_to_gnutls_session (session, 1, FUNC_NAME);
data = (char *) SCM_BYTEVECTOR_CONTENTS (src) + start;
- result = gnutls_record_send (c_session, data, count);
+ do
+ result = gnutls_record_send (c_session, data, count);
+ while (result == GNUTLS_E_INTERRUPTED
+ || (result == GNUTLS_E_AGAIN
+ && !SCM_GNUTLS_SESSION_TRANSPORT_IS_FD (c_session)));
+
+ if (result == GNUTLS_E_AGAIN
+ && SCM_GNUTLS_SESSION_TRANSPORT_IS_FD (c_session))
+ /* Tell Guile that reading would block. */
+ return (size_t) -1;
if (EXPECT_FALSE (result < 0))
scm_gnutls_error (result, FUNC_NAME);

View file

@ -180,7 +180,8 @@ (define-public gnutls
(version-major+minor version)
"/gnutls-" version ".tar.xz"))
(patches (search-patches "gnutls-skip-trust-store-test.patch"
"gnutls-cross.patch"))
"gnutls-cross.patch"
"gnutls-guile-eintr-eagain.patch"))
(sha256
(base32
"0li7mwjnm64mbxhacz0rpf6i9qd83f53fvbrx96alpqqk9d6qvk4"))))