Index: peripherals/nic/w5100_internals.h
===================================================================
--- peripherals/nic/w5100_internals.h (revision 4648)
+++ peripherals/nic/w5100_internals.h (working copy)
@@ -29,6 +29,10 @@
#ifndef FUSE_W5100_INTERNALS_H
#define FUSE_W5100_INTERNALS_H
+#ifdef WIN32
+#include <signal.h>
+#endif /* #ifdef WIN32 */
+
typedef enum w5100_socket_mode {
W5100_SOCKET_MODE_CLOSED = 0x00,
W5100_SOCKET_MODE_TCP,
Index: peripherals/nic/w5100_socket.c
===================================================================
--- peripherals/nic/w5100_socket.c (revision 4648)
+++ peripherals/nic/w5100_socket.c (working copy)
@@ -34,9 +34,7 @@
#include <unistd.h>
#ifdef WIN32
-#include <winsock.h>
-#include <signal.h>
-typedef int socklen_t;
+#include <winsock2.h>
#else
#include <arpa/inet.h>
#include <netinet/in.h>
@@ -181,7 +179,6 @@
int protocol = tcp ? IPPROTO_TCP : IPPROTO_UDP;
const char *description = tcp ? "TCP" : "UDP";
int final_state = tcp ? W5100_SOCKET_STATE_INIT : W5100_SOCKET_STATE_UDP;
- int one = 1;
w5100_socket_clean( socket_obj );
@@ -195,12 +192,17 @@
return;
}
+#ifndef WIN32
+ int one = 1;
+
+ /* Windows warning: this could forcibly bind sockets already in use */
if( setsockopt( socket_obj->fd, SOL_SOCKET, SO_REUSEADDR, &one,
sizeof(one) ) == -1 ) {
nic_w5100_error( UI_ERROR_ERROR,
"w5100: failed to set SO_REUSEADDR on socket %d; errno %d: %s\n",
socket_obj->id, compat_socket_get_error(), compat_socket_get_error() );
}
+#endif
socket_obj->state = final_state;
@@ -423,6 +425,7 @@
if( w5100_socket_bind_port( self, socket ) ) {
w5100_socket_release_lock( socket );
socket->bind_count = 0;
+ return;
}
w5100_socket_release_lock( socket );
compat_socket_selfpipe_wake( self->selfpipe );
@@ -617,7 +620,7 @@
nic_w5100_debug( "w5100: accepted connection from %s:%d on socket %d\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), socket->id );
- if( close( socket->fd ) == -1 )
+ if( compat_socket_close( socket->fd ) == -1 )
nic_w5100_debug( "w5100: error attempting to close fd %d for socket %d\n", socket->fd, socket->id );
socket->fd = new_fd;
Index: peripherals/nic/w5100.c
===================================================================
--- peripherals/nic/w5100.c (revision 4648)
+++ peripherals/nic/w5100.c (working copy)
@@ -28,19 +28,11 @@
#include "config.h"
-#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
-#ifdef WIN32
-#include <signal.h>
-#else
-#include <netinet/in.h>
-#include <sys/socket.h>
-#endif
-
#include "fuse.h"
#include "ui/ui.h"
#include "w5100.h"
@@ -400,20 +392,7 @@
{
va_list ap;
-#ifdef WIN32
- /* pause because contents of the audio buffer are played into a loop */
- fuse_emulation_pause();
-#endif
-
va_start( ap, format );
nic_w5100_vdebug( format, ap );
va_end( ap );
-
- va_start( ap, format );
- ui_verror( severity, format, ap );
- va_end( ap );
-
-#ifdef WIN32
- fuse_emulation_unpause();
-#endif
}
Index: compat/win32/socket.c
===================================================================
--- compat/win32/socket.c (revision 4648)
+++ compat/win32/socket.c (working copy)
@@ -1,4 +1,4 @@
-/* file.c: Socket-related compatibility routines
+/* socket.c: Socket-related compatibility routines
Copyright (c) 2011 Sergio BaldovĂ, Philip Kendall
$Id$
@@ -25,8 +25,8 @@
#include <config.h>
-#include <winsock.h>
-typedef int socklen_t;
+#include <winsock2.h>
+#include <ws2tcpip.h>
#include "compat.h"
#include "fuse.h"
@@ -37,9 +37,11 @@
struct compat_socket_selfpipe_t {
SOCKET self_socket;
- int port;
+ libspectrum_word port;
};
+int compat_socket_selfpipe_test( compat_socket_selfpipe_t *self );
+
int
compat_socket_close( compat_socket_t fd )
{
@@ -129,7 +131,14 @@
fuse_abort();
}
- self->port = sa.sin_port;
+ self->port = ntohs( sa.sin_port );
+
+ /* Test communications in order to detect blocking firewalls */
+ if( compat_socket_selfpipe_test( self ) == -1 ) {
+ ui_error( UI_ERROR_ERROR,
+ "w5100: failed to test internal communications" );
+ fuse_abort();
+ }
return self;
}
@@ -152,7 +161,7 @@
memset( &sa, 0, sizeof(sa) );
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
- memcpy( &sa.sin_port, self->port, 2 );
+ sa.sin_port = htons( self->port );
sendto( self->self_socket, NULL, 0, 0, (struct sockaddr*)&sa, sizeof(sa) );
}
@@ -171,6 +180,32 @@
} while( bytes_read != -1 );
}
+int
+compat_socket_selfpipe_test( compat_socket_selfpipe_t *self )
+{
+ fd_set readfds;
+ int active;
+ struct timeval tv = { 1, 0 };
+
+ /* Send testing packet */
+ compat_socket_selfpipe_wake( self );
+
+ /* Safe reading from control socket */
+ FD_ZERO( &readfds );
+ FD_SET( self->self_socket, &readfds );
+ active = select( 0, &readfds, NULL, NULL, &tv );
+ if( active == 0 || active == compat_socket_invalid ) {
+ return -1;
+ }
+
+ /* Discard testing packet */
+ if( FD_ISSET( self->self_socket, &readfds ) ) {
+ compat_socket_selfpipe_discard_data( self );
+ }
+
+ return 0;
+}
+
void
compat_socket_networking_init( void )
{
Index: compat/unix/socket.c
===================================================================
--- compat/unix/socket.c (revision 4648)
+++ compat/unix/socket.c (working copy)
@@ -1,4 +1,4 @@
-/* file.c: Socket-related compatibility routines
+/* socket.c: Socket-related compatibility routines
Copyright (c) 2011 Philip Kendall
$Id$
(c) 2011 Philip Kendall
$Id$