diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2017-06-26 23:15:22 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2017-07-03 15:45:25 +0200 |
commit | c0cdc68c7eacaa4fda3e2324f8618b6bbe038983 (patch) | |
tree | d1b191bc2d7800a89f8be851ced14f76e2b4bb5e | |
parent | 3a48a132685ca891ce1b7a10bbcd4b4cd33cee5e (diff) |
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: Johannes Schindelin <johannes.schindelin@gmx.de>
-rw-r--r-- | lib/vtls/gtls.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index cbbb61f76..d55f995e8 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -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; } |