Hello, Manuel,
I apologize for the mistake, but I just realized I had left a debugging printf
and omitted a semi-colon in the csocket.patch I originally sent. I have
attached an updated version.
Best Regards,
Joe
On Saturday, February 15, 2014 8:47 AM, Joseph Donaldson
<[email protected]> wrote:
Hello, Manuel,
>
>Please find attached the patches required to have bigloo4.1a compile under
>MinGW. The patches are against bigloo4.1a-beta12Feb14. inet_pton.patch,
>inet_aton.patch, and getaddrinfo.patch modify the corresponding autoconf
>programs to report that getaddrinfo is available but inet_pton and inet_aton
>are not. cdate.patch modifies to cdate.c so that 32bit time_t values are used
>instead of the default 64bit. cunicode.patch just changes the type ulong to
>unsigned long; ulong does not seem to be defined on MinGW. For gc_intf.patch,
>the GC_API modifier was added to bgl_gc_init so that is exported from the
>libbigloogc and libbigloogc_fth. csystem.patch added a definition for gid_t
>which is not defined under MinGW. socket.patch adds %socket-init! calls to the
>datagram socket
constructors. csocket.patch makes the necessary changes to have the datagram
socket code compile under MinGW.
>
>
>
>Best Regards,
>Joseph Donaldson
>
>
>
>
>On Thursday, February 13, 2014 11:44 PM, "[email protected]"
><[email protected]> wrote:
>
>Hi Joseph,
>>
>>> I will provide the patch in the next day or so. Most of the changes are
>>> very small (e.g., adding the GC_API modifier to bgl_gc_init in gc_intf.c
>>> and providing a define for gid_t in csystem.c). However, the changes
>>> required to csocket.c were a bit more substantial and I am still testing
>>> them.
>>Good. Thanks in advance for this contribution.
>>
>>--
>>Manuel
>>
>>
>>
>
>
--- bigloo4.1a/runtime/Clib/csocket.c 2014-02-12 04:08:00 -0500
+++ bigloo4.1a_mod/runtime/Clib/csocket.c 2014-02-15 08:28:26 -0500
@@ -20,12 +20,17 @@
/*=====================================================================*/
#if defined( _MSC_VER) || defined( _MINGW_VER )
# define _BGL_WIN32_VER
+# define WINVER _WIN32_WINNT_WINXP /* minimum supported windows version XP */
+# define _WIN32_WINNT _WIN32_WINNT_WINXP
+# define __MSYS__ 1 /* disable inclusion of winsock.h in windows.h */
+#
#endif
#include <stddef.h>
#include <bigloo_config.h>
#include <time.h>
#ifndef _BGL_WIN32_VER
+# define SOCKOPTVALTYPE void*
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
@@ -43,13 +48,17 @@
# include <unistd.h>
# endif
#else
+# define SOCKOPTVALTYPE char*
# if defined( _MINGW_VER )
# include "windows.h"
# endif
-# include <winsock2.h>
-# include <mswsock.h>
+
# include <ws2tcpip.h>
+# include <mswsock.h>
# include <io.h>
+# ifndef AI_ADDRCONFIG
+# define AI_ADDRCONFIG 0
+# endif
#endif
#include <fcntl.h>
#include <memory.h>
@@ -970,7 +979,7 @@
#if( BGL_HAVE_GETHWADDRS )
struct ifreq buffer;
int s;
- if( (s = socket( PF_INET, SOCK_DGRAM, 0 )) == -1 ) {
+ if( BAD_SOCKET(s = socket( PF_INET, SOCK_DGRAM, 0 ))) {
return BFALSE;
} else {
char buf[ 6 * 3 + 1 ];
@@ -1053,7 +1062,7 @@
obj_t res = BNIL;
void *tmpAddrPtr = 0L;
- if( (fd = socket( AF_INET, SOCK_DGRAM, 0 )) >= 0 ) {
+ if( !BAD_SOCKET(fd = socket( AF_INET, SOCK_DGRAM, 0 ))) {
conf.ifc_len = sizeof( data );
conf.ifc_buf = (caddr_t)data;
@@ -1113,7 +1122,7 @@
result = setsockopt( INVALID_SOCKET,
SOL_SOCKET, SO_OPENTYPE,
- (const char *)&val,
+ (SOCKOPTVALTYPE)&val,
sizeof( val ) );
if( 0 != result ) {
socket_error( "make_server_socket",
@@ -1368,7 +1377,7 @@
tcp_client_socket_error( hostname, port, "Connection failed", errno );
} else {
int len = sizeof( int );
- int r = getsockopt( s, SOL_SOCKET, SO_ERROR, (void *)&err, (socklen_t *)&len );
+ int r = getsockopt( s, SOL_SOCKET, SO_ERROR, (SOCKOPTVALTYPE)&err, (socklen_t *)&len );
if( (r < 0) || (err != 0) ) {
/* we have experienced a failure so we */
@@ -1515,7 +1524,7 @@
/* set the reuse flag */
if( setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
- &sock_opt, sizeof( sock_opt ) ) < 0 ) {
+ (SOCKOPTVALTYPE)&sock_opt, sizeof( sock_opt ) ) < 0 ) {
system_error( msg, BINT( portnum ) );
}
@@ -1597,7 +1606,7 @@
if( shutdown( fd, SHUT_RDWR ) ) {
char *buffer = alloca( 1024 );
- sprintf( buffer, "cannot shutdown socket, %s", strerror( errno ) );
+ sprintf( buffer, "cannot shutdown socket, %s", strerror( errno ));
socket_error( "socket-shutdown", buffer, sock );
}
}
@@ -1793,13 +1802,10 @@
struct hostent *host = 0;
char *hip = BSTRING_TO_STRING( hostip );
-#if( BGL_HAVE_INET_ATON || BGL_HAVE_INET_PTON )
struct sockaddr_in sin;
-#else
- struct sockaddr_in *sin;
-#endif
+
-#if( BGL_HAVE_GETADDRINFO )
+#if( BGL_HAVE_INET_ATON || BGL_HAVE_INET_PTON)
socklen_t len = sizeof( sin );
/* cannot fail because we have created the socket */
@@ -1809,19 +1815,22 @@
sin.sin_family = AF_INET;
}
#endif
+
+
#if( BGL_HAVE_INET_ATON )
/* For IPv4 prefer inet_aton when available because it */
/* supports more IP format than inet_pton. */
if( inet_aton( BSTRING_TO_STRING( hostip ), &(sin.sin_addr) ) )
host = bglhostbyaddr( &sin );
+
#else
# if( BGL_HAVE_INET_PTON )
if( inet_pton( AF_INET, BSTRING_TO_STRING( hostip ), &sin.sin_addr ) )
host = bglhostbyaddr( &sin );
# else
- sin = inet_addr( hostip );
- host = bglhostbyaddr( sin );
+ sin.sin_addr.s_addr = inet_addr( BSTRING_TO_STRING( hostip ) );
+ host = bglhostbyaddr( &sin );
# endif
#endif
@@ -1995,7 +2004,7 @@
type _v; \
socklen_t _l = sizeof( type ); \
\
- if( getsockopt( SOCKET( s ).fd, level, optname, &_v, &_l ) ) { \
+ if( getsockopt( SOCKET( s ).fd, level, optname, (SOCKOPTVALTYPE)&_v, &_l ) ) { \
return BUNSPEC; \
} else { \
return conv( _v ); \
@@ -2010,7 +2019,7 @@
type _v = val; \
socklen_t _l = sizeof( type ); \
\
- if( setsockopt( SOCKET( s ).fd, level, optname, &_v, _l ) ) { \
+ if( setsockopt( SOCKET( s ).fd, level, optname, (SOCKOPTVALTYPE)&_v, _l ) ) { \
return BFALSE; \
} else { \
return s; \
@@ -2270,7 +2279,7 @@
mreq.imr_interface.s_addr = htonl( INADDR_ANY );
if( setsockopt( SOCKET( socket ).fd, IPPROTO_IP,
- IP_ADD_MEMBERSHIP, &mreq, sizeof( struct ip_mreq ) ) )
+ IP_ADD_MEMBERSHIP, (SOCKOPTVALTYPE)&mreq, sizeof( struct ip_mreq ) ) )
return BFALSE;
else
return socket;
@@ -2287,7 +2296,7 @@
mreq.imr_multiaddr.s_addr = inet_addr( BSTRING_TO_STRING( val ) );
mreq.imr_interface.s_addr = htonl( INADDR_ANY );
if( setsockopt( SOCKET( socket ).fd, IPPROTO_IP,
- IP_DROP_MEMBERSHIP, &mreq, sizeof( struct ip_mreq ) ) )
+ IP_DROP_MEMBERSHIP, (SOCKOPTVALTYPE)&mreq, sizeof( struct ip_mreq ) ) )
return BFALSE;
else
return socket;
@@ -2326,11 +2335,18 @@
sock );
}
- if( (n = sendto( fd, buf, len, 0,
+ #ifdef _BGL_WIN32_VER
+ SOCKET s2 = _get_osfhandle(fd);
+ n = sendto( s2, buf, len, 0,
+ (struct sockaddr *)&BGL_DATAGRAM_SOCKET( sock ).server,
+ sizeof( struct sockaddr_in ));
+ #else
+ n = sendto( fd, buf, len, 0,
(struct sockaddr *)&BGL_DATAGRAM_SOCKET( sock ).server,
- sizeof( struct sockaddr_in ) )) == -1 ) {
+ sizeof( struct sockaddr_in ));
+ #endif
+ if( n == -1 ) {
char buffer[ 512 ];
-
sprintf( buffer, "%s (%d)", strerror( errno ), errno );
C_SYSTEM_FAILURE( BGL_IO_PORT_ERROR,
@@ -2372,10 +2388,12 @@
datagram_client_socket_error( hostname, port, "cannot create socket", errno );
}
+
+
// configure the socket
if( broadcast ) {
int bcast = 1;
- if( setsockopt( s, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof( bcast ) ) == -1) {
+ if( setsockopt( s, SOL_SOCKET, SO_BROADCAST, (SOCKOPTVALTYPE)&bcast, sizeof( bcast ) ) == -1) {
datagram_client_socket_error( hostname, port,
"cannot configure socket for broadcast",
errno );
@@ -2400,6 +2418,9 @@
a_socket->datagram_socket_t.hostname = hname;
a_socket->datagram_socket_t.hostip = string_to_bstring( inet_ntoa( server->sin_addr ) );
a_socket->datagram_socket_t.stype = BGL_SOCKET_CLIENT;
+ #ifdef _BGL_WIN32_VER
+ s = _open_osfhandle( s, _O_RDWR );
+ #endif
a_socket->datagram_socket_t.fd = s;
/* socket port */
@@ -2463,13 +2484,13 @@
for( p = servinfo; p != NULL; p = p->ai_next ) {
int sock_opt = 1;
- if( (s = socket( p->ai_family, p->ai_socktype, p->ai_protocol )) == -1 ) {
+ if( BAD_SOCKET(s = (int)socket( p->ai_family, p->ai_socktype, p->ai_protocol ))) {
socket_error( msg, "cannot create socket", BINT( portnum ) );
}
/* set the reuse flag */
if( setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
- &sock_opt, sizeof( sock_opt ) ) < 0 ) {
+ (SOCKOPTVALTYPE)&sock_opt, sizeof( sock_opt ) ) < 0 ) {
system_error( msg, BINT( portnum ) );
}
@@ -2489,6 +2510,9 @@
sock->datagram_socket_t.portnum = portnum;
sock->datagram_socket_t.hostname = BUNSPEC;
sock->datagram_socket_t.hostip = BFALSE;
+ #ifdef _BGL_WIN32_VER
+ s = _open_osfhandle( s, _O_RDWR );
+ #endif
sock->datagram_socket_t.fd = s;
sock->datagram_socket_t.stype = BGL_SOCKET_SERVER;
@@ -2538,7 +2562,7 @@
socket_error( msg, "unsupported socket family", family );
}
- if( (s = socket( fam, SOCK_DGRAM, 0 )) == -1 ) {
+ if( BAD_SOCKET(s = (int)socket( fam, SOCK_DGRAM, 0 ))) {
socket_error( msg, "cannot create socket", family );
}
@@ -2547,6 +2572,9 @@
sock->datagram_socket_t.portnum = 0;
sock->datagram_socket_t.hostname = BUNSPEC;
sock->datagram_socket_t.hostip = BFALSE;
+ #ifdef _BGL_WIN32_VER
+ s = _open_osfhandle( s, _O_RDWR );
+ #endif
sock->datagram_socket_t.fd = s;
sock->datagram_socket_t.stype = BGL_SOCKET_SERVER;
@@ -2670,8 +2698,16 @@
}
addr_len = sizeof( their_addr );
- if( (n = recvfrom( fd, buf, sz - 1 , 0,
- (struct sockaddr *)&their_addr, &addr_len )) == -1 ) {
+
+ #ifdef _BGL_WIN32_VER
+ SOCKET s2 = _get_osfhandle(fd);
+ n = recvfrom( s2, buf, sz - 1 , 0,
+ (struct sockaddr *)&their_addr, &addr_len );
+ #else
+ n = recvfrom( fd, buf, sz - 1 , 0,
+ (struct sockaddr *)&their_addr, &addr_len );
+ #endif
+ if( n == -1 ) {
socket_error( "datagram-socket-receive", "cannot receive datagram", sock );
} else {
obj_t env = BGL_CURRENT_DYNAMIC_ENV();
@@ -2711,6 +2747,7 @@
sock );
}
+#if BGL_HAVE_INET_PTON
/* FIXME: No support for AF_UNIX, etc. */
if( !inet_pton( AF_INET, BSTRING_TO_STRING( host ),
&((struct sockaddr_in *)&their_addr)->sin_addr ) ) {
@@ -2729,8 +2766,66 @@
slen = sizeof( struct sockaddr_in );
}
+#elif BGL_HAVE_GETADDRINFO
+ {
+ struct addrinfo hints;
+ struct addrinfo *results = NULL;
+ int ret = 0;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+
+ ret = getaddrinfo(BSTRING_TO_STRING( host ),
+ NULL,
+ &hints,
+ &results);
+
+ if(0 != ret || NULL == results){
+ socket_error( "datagram-socket-send",
+ "cannot convert destination address", sock );
+ } else {
+ /* only use the first result */
+ if(AF_INET6 == results->ai_family){
+
+ ((struct sockaddr_in6 *)&their_addr)->sin6_addr = ((struct sockaddr_in6*)&(results->ai_addr))->sin6_addr;
+ ((struct sockaddr_in6 *)&their_addr)->sin6_port = htons( port );
+ ((struct sockaddr *)&their_addr)->sa_family = AF_INET6;
+ slen = sizeof( struct sockaddr_in6 );
+
+ } else if (AF_INET == results->ai_family){
+
+ ((struct sockaddr_in *)&their_addr)->sin_addr = ((struct sockaddr_in*)&(results->ai_addr))->sin_addr;
+ ((struct sockaddr_in *)&their_addr)->sin_port = htons( port );
+ ((struct sockaddr *)&their_addr)->sa_family = AF_INET;
+ slen = sizeof( struct sockaddr_in );
+
+ }
+
+ }
+
+ if(NULL != results){
+ freeaddrinfo(results);
+ }
+ }
+#else
+
+#error "inet_pton or getaddrinfo needed for bgl_datagram_socket_send"
+
+#endif /* BGL_HAVE_INET_PTON */
+
+
+ #ifdef _BGL_WIN32_VER
+ SOCKET s2 = _get_osfhandle(fd);
+ sent = sendto( s2, BSTRING_TO_STRING( str ), STRING_LENGTH( str ), 0,
+ (struct sockaddr *) &their_addr, slen );
+
+ #else
sent = sendto( fd, BSTRING_TO_STRING( str ), STRING_LENGTH( str ), 0,
(struct sockaddr *) &their_addr, slen );
+ #endif
if( sent < 0 ) {
socket_error( "datagram-socket-send", "cannot send datagram", sock );
}