Commit c0cdc68c authored by Johannes Schindelin's avatar Johannes Schindelin Committed by Daniel Stenberg
Browse files

gtls: fix build when sizeof(long) < sizeof(void *)



- Change gnutls pointer/int macros to pointer/curl_socket_t.
  Prior to this change they used long type as well.

The size of the `long` data type can be shorter than that of pointer
types. This is the case most notably on Windows.

If C99 were acceptable, we could simply use `intptr_t` here. But we
want to retain C89 compatibility.

Simply use the trick of performing pointer arithmetic with the NULL
pointer: to convert an integer `i` to a pointer, simply take the
address of the `i`th element of a hypothetical character array
starting at address NULL. To convert back, simply cast the pointer
difference.

Thanks to Jay Satiro for the initial modification to use curl_socket_t
instead of int/long.

Closes #1617

Signed-off-by: default avatarJohannes Schindelin <johannes.schindelin@gmx.de>
parent 3a48a132
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -60,15 +60,13 @@
/* The last #include file should be: */
#include "memdebug.h"

/*
 Some hackish cast macros based on:
 https://developer.gnome.org/glib/unstable/glib-Type-Conversion-Macros.html
*/
#ifndef GNUTLS_POINTER_TO_INT_CAST
#define GNUTLS_POINTER_TO_INT_CAST(p) ((int) (long) (p))
#ifndef GNUTLS_POINTER_TO_SOCKET_CAST
#define GNUTLS_POINTER_TO_SOCKET_CAST(p) \
  ((curl_socket_t) ((char *)(p) - (char *)NULL))
#endif
#ifndef GNUTLS_INT_TO_POINTER_CAST
#define GNUTLS_INT_TO_POINTER_CAST(i) ((void *) (long) (i))
#ifndef GNUTLS_SOCKET_TO_POINTER_CAST
#define GNUTLS_SOCKET_TO_POINTER_CAST(s) \
  ((void *) ((char *)NULL + (s)))
#endif

/* Enable GnuTLS debugging by defining GTLSDEBUG */
@@ -153,7 +151,7 @@ static int gtls_mapped_sockerrno(void)

static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
{
  ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
  ssize_t ret = swrite(GNUTLS_POINTER_TO_SOCKET_CAST(s), buf, len);
#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
  if(ret < 0)
    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
@@ -163,7 +161,7 @@ static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)

static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
{
  ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
  ssize_t ret = sread(GNUTLS_POINTER_TO_SOCKET_CAST(s), buf, len);
#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
  if(ret < 0)
    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
@@ -850,7 +848,7 @@ gtls_connect_step1(struct connectdata *conn,
  }
  else {
    /* file descriptor for the socket */
    transport_ptr = GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]);
    transport_ptr = GNUTLS_SOCKET_TO_POINTER_CAST(conn->sock[sockindex]);
    gnutls_transport_push = Curl_gtls_push;
    gnutls_transport_pull = Curl_gtls_pull;
  }