[gnutls-devel] [PATCH 3/3] guile: Implement session record ports using the Guile 2.2 API.
Ludovic Courtès
ludo at gnu.org
Wed Oct 5 14:30:33 CEST 2016
This allows the Guile bindings to be built and used with
Guile >= 2.1.4, which introduced a new port API.
* guile/src/core.c (USING_GUILE_BEFORE_2_2): New macro.
(session_record_port_type) [!USING_GUILE_BEFORE_2_2]: New definition.
(read_from_session_record_port, write_to_session_record_port)
(make_session_record_port) [!USING_GUILE_BEFORE_2_2]: New functions.
Conditionalize the other same-named functions on
USING_GUILE_BEFORE_2_2.
(scm_init_gnutls_session_record_port_type): Use
'read_from_session_record_port' when !USING_GUILE_BEFORE_2_2.
---
guile/src/core.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 82 insertions(+), 5 deletions(-)
diff --git a/guile/src/core.c b/guile/src/core.c
index a42ba76..605c91f 100644
--- a/guile/src/core.c
+++ b/guile/src/core.c
@@ -1,5 +1,5 @@
/* GnuTLS --- Guile bindings for GnuTLS.
- Copyright (C) 2007-2014 Free Software Foundation, Inc.
+ Copyright (C) 2007-2014, 2016 Free Software Foundation, Inc.
GnuTLS is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,7 +15,7 @@
License along with GnuTLS; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* Written by Ludovic Courtès <ludo at gnu.org>. */
+/* Written by Ludovic Courtès <ludo at gnu.org>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -782,8 +782,18 @@ SCM_DEFINE (scm_gnutls_record_receive_x, "record-receive!", 2, 0, 0,
#undef FUNC_NAME
-/* The session record port type. */
+/* Whether we're using Guile < 2.2. */
+#define USING_GUILE_BEFORE_2_2 \
+ (SCM_MAJOR_VERSION < 2 \
+ || (SCM_MAJOR_VERSION == 2 && SCM_MINOR_VERSION == 0))
+
+/* The session record port type. Guile 2.1.4 introduced a brand new port API,
+ so we have a separate implementation for these newer versions. */
+#if USING_GUILE_BEFORE_2_2
static scm_t_bits session_record_port_type;
+#else
+static scm_t_port_type *session_record_port_type;
+#endif
/* Return the session associated with PORT. */
#define SCM_GNUTLS_SESSION_RECORD_PORT_SESSION(_port) \
@@ -840,6 +850,8 @@ free_session_record_port (SCM port)
#endif /* SCM_MAJOR_VERSION == 1 && SCM_MINOR_VERSION <= 8 */
+#if USING_GUILE_BEFORE_2_2
+
/* Data passed to `do_fill_port ()'. */
typedef struct
{
@@ -937,7 +949,7 @@ write_to_session_record_port (SCM port, const void *data, size_t size)
#undef FUNC_NAME
/* Return a new session port for SESSION. */
-static inline SCM
+static SCM
make_session_record_port (SCM session)
{
SCM port;
@@ -972,6 +984,67 @@ make_session_record_port (SCM session)
return (port);
}
+#else /* !USING_GUILE_BEFORE_2_2 */
+
+static size_t
+read_from_session_record_port (SCM port, SCM dst, size_t start, size_t count)
+#define FUNC_NAME "read_from_session_record_port"
+{
+ SCM session;
+ gnutls_session_t c_session;
+ char *read_buf;
+ ssize_t result;
+
+ session = SCM_GNUTLS_SESSION_RECORD_PORT_SESSION (port);
+ c_session = scm_to_gnutls_session (session, 1, FUNC_NAME);
+
+ read_buf = (char *) SCM_BYTEVECTOR_CONTENTS (dst) + start;
+
+ /* XXX: Leave guile mode when SCM_GNUTLS_SESSION_TRANSPORT_IS_FD is
+ true? */
+ result = gnutls_record_recv (c_session, read_buf, count);
+ if (EXPECT_FALSE (result < 0))
+ /* FIXME: Silently swallowed! */
+ scm_gnutls_error (result, FUNC_NAME);
+
+ return result;
+}
+#undef FUNC_NAME
+
+static size_t
+write_to_session_record_port (SCM port, SCM src, size_t start, size_t count)
+#define FUNC_NAME "write_to_session_record_port"
+{
+ SCM session;
+ gnutls_session_t c_session;
+ char *data;
+ ssize_t result;
+
+ session = SCM_GNUTLS_SESSION_RECORD_PORT_SESSION (port);
+ 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);
+
+ if (EXPECT_FALSE (result < 0))
+ scm_gnutls_error (result, FUNC_NAME);
+
+ return result;
+}
+#undef FUNC_NAME
+
+/* Return a new session port for SESSION. */
+static SCM
+make_session_record_port (SCM session)
+{
+ return scm_c_make_port (session_record_port_type,
+ SCM_OPN | SCM_RDNG | SCM_WRTNG | SCM_BUF0,
+ SCM_UNPACK (session));
+}
+
+#endif /* !USING_GUILE_BEFORE_2_2 */
+
+
SCM_DEFINE (scm_gnutls_session_record_port, "session-record-port", 1, 0, 0,
(SCM session),
"Return a read-write port that may be used to communicate over "
@@ -999,12 +1072,16 @@ SCM_DEFINE (scm_gnutls_session_record_port, "session-record-port", 1, 0, 0,
#undef FUNC_NAME
/* Create the session port type. */
-static inline void
+static void
scm_init_gnutls_session_record_port_type (void)
{
session_record_port_type =
scm_make_port_type ("gnutls-session-port",
+#if USING_GUILE_BEFORE_2_2
fill_session_record_port_input,
+#else
+ read_from_session_record_port,
+#endif
write_to_session_record_port);
/* Guile >= 1.9.3 doesn't need a custom mark procedure, and doesn't need a
--
2.10.0
More information about the Gnutls-devel
mailing list