1. Index: peripherals/nic/w5100_internals.h
  2. ===================================================================
  3. --- peripherals/nic/w5100_internals.h   (revision 4648)
  4. +++ peripherals/nic/w5100_internals.h   (working copy)
  5. @@ -29,6 +29,10 @@
  6.  #ifndef FUSE_W5100_INTERNALS_H
  7.  #define FUSE_W5100_INTERNALS_H
  8.  
  9. +#ifdef WIN32
  10. +#include <signal.h>
  11. +#endif             /* #ifdef WIN32 */
  12. +
  13.  typedef enum w5100_socket_mode {
  14.    W5100_SOCKET_MODE_CLOSED = 0x00,
  15.    W5100_SOCKET_MODE_TCP,
  16. Index: peripherals/nic/w5100_socket.c
  17. ===================================================================
  18. --- peripherals/nic/w5100_socket.c  (revision 4648)
  19. +++ peripherals/nic/w5100_socket.c  (working copy)
  20. @@ -34,9 +34,7 @@
  21.  #include <unistd.h>
  22.  
  23.  #ifdef WIN32
  24. -#include <winsock.h>
  25. -#include <signal.h>
  26. -typedef int socklen_t;
  27. +#include <winsock2.h>
  28.  #else
  29.  #include <arpa/inet.h>
  30.  #include <netinet/in.h>
  31. @@ -181,7 +179,6 @@
  32.      int protocol = tcp ? IPPROTO_TCP : IPPROTO_UDP;
  33.      const char *description = tcp ? "TCP" : "UDP";
  34.      int final_state = tcp ? W5100_SOCKET_STATE_INIT : W5100_SOCKET_STATE_UDP;
  35. -    int one = 1;
  36.  
  37.      w5100_socket_clean( socket_obj );
  38.  
  39. @@ -195,12 +192,17 @@
  40.        return;
  41.      }
  42.  
  43. +#ifndef WIN32
  44. +    int one = 1;
  45. +
  46. +    /* Windows warning: this could forcibly bind sockets already in use */
  47.      if( setsockopt( socket_obj->fd, SOL_SOCKET, SO_REUSEADDR, &one,
  48.        sizeof(one) ) == -1 ) {
  49.        nic_w5100_error( UI_ERROR_ERROR,
  50.          "w5100: failed to set SO_REUSEADDR on socket %d; errno %d: %s\n",
  51.          socket_obj->id, compat_socket_get_error(), compat_socket_get_error() );
  52.      }
  53. +#endif
  54.  
  55.      socket_obj->state = final_state;
  56.  
  57. @@ -423,6 +425,7 @@
  58.        if( w5100_socket_bind_port( self, socket ) ) {
  59.          w5100_socket_release_lock( socket );
  60.          socket->bind_count = 0;
  61. +        return;
  62.        }
  63.        w5100_socket_release_lock( socket );
  64.        compat_socket_selfpipe_wake( self->selfpipe );
  65. @@ -617,7 +620,7 @@
  66.  
  67.    nic_w5100_debug( "w5100: accepted connection from %s:%d on socket %d\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), socket->id );
  68.  
  69. -  if( close( socket->fd ) == -1 )
  70. +  if( compat_socket_close( socket->fd ) == -1 )
  71.      nic_w5100_debug( "w5100: error attempting to close fd %d for socket %d\n", socket->fd, socket->id );
  72.  
  73.    socket->fd = new_fd;
  74. Index: peripherals/nic/w5100.c
  75. ===================================================================
  76. --- peripherals/nic/w5100.c (revision 4648)
  77. +++ peripherals/nic/w5100.c (working copy)
  78. @@ -28,19 +28,11 @@
  79.  
  80.  #include "config.h"
  81.  
  82. -#include <errno.h>
  83.  #include <pthread.h>
  84.  #include <string.h>
  85.  #include <sys/types.h>
  86.  #include <unistd.h>
  87.  
  88. -#ifdef WIN32
  89. -#include <signal.h>
  90. -#else
  91. -#include <netinet/in.h>
  92. -#include <sys/socket.h>
  93. -#endif
  94. -
  95.  #include "fuse.h"
  96.  #include "ui/ui.h"
  97.  #include "w5100.h"
  98. @@ -400,20 +392,7 @@
  99.  {
  100.    va_list ap;
  101.  
  102. -#ifdef WIN32
  103. -  /* pause because contents of the audio buffer are played into a loop */
  104. -  fuse_emulation_pause();
  105. -#endif
  106. -
  107.    va_start( ap, format );
  108.    nic_w5100_vdebug( format, ap );
  109.    va_end( ap );
  110. -
  111. -  va_start( ap, format );
  112. -  ui_verror( severity, format, ap );
  113. -  va_end( ap );
  114. -
  115. -#ifdef WIN32
  116. -  fuse_emulation_unpause();
  117. -#endif
  118.  }
  119. Index: compat/win32/socket.c
  120. ===================================================================
  121. --- compat/win32/socket.c   (revision 4648)
  122. +++ compat/win32/socket.c   (working copy)
  123. @@ -1,4 +1,4 @@
  124. -/* file.c: Socket-related compatibility routines
  125. +/* socket.c: Socket-related compatibility routines
  126.     Copyright (c) 2011 Sergio BaldovĂ­, Philip Kendall
  127.  
  128.     $Id$
  129. @@ -25,8 +25,8 @@
  130.  
  131.  #include <config.h>
  132.  
  133. -#include <winsock.h>
  134. -typedef int socklen_t;
  135. +#include <winsock2.h>
  136. +#include <ws2tcpip.h>
  137.  
  138.  #include "compat.h"
  139.  #include "fuse.h"
  140. @@ -37,9 +37,11 @@
  141.  
  142.  struct compat_socket_selfpipe_t {
  143.    SOCKET self_socket;
  144. -  int port;
  145. +  libspectrum_word port;
  146.  };
  147.  
  148. +int compat_socket_selfpipe_test( compat_socket_selfpipe_t *self );
  149. +
  150.  int
  151.  compat_socket_close( compat_socket_t fd )
  152.  {
  153. @@ -129,7 +131,14 @@
  154.      fuse_abort();
  155.    }
  156.  
  157. -  self->port = sa.sin_port;
  158. +  self->port = ntohs( sa.sin_port );
  159. +
  160. +  /* Test communications in order to detect blocking firewalls */
  161. +  if( compat_socket_selfpipe_test( self ) == -1 ) {
  162. +    ui_error( UI_ERROR_ERROR,
  163. +              "w5100: failed to test internal communications" );
  164. +    fuse_abort();
  165. +  }
  166.  
  167.    return self;
  168.  }
  169. @@ -152,7 +161,7 @@
  170.    memset( &sa, 0, sizeof(sa) );
  171.    sa.sin_family = AF_INET;
  172.    sa.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
  173. -  memcpy( &sa.sin_port, self->port, 2 );
  174. +  sa.sin_port = htons( self->port );
  175.  
  176.    sendto( self->self_socket, NULL, 0, 0, (struct sockaddr*)&sa, sizeof(sa) );
  177.  }
  178. @@ -171,6 +180,32 @@
  179.    } while( bytes_read != -1 );
  180.  }
  181.  
  182. +int
  183. +compat_socket_selfpipe_test( compat_socket_selfpipe_t *self )
  184. +{
  185. +  fd_set readfds;
  186. +  int active;
  187. +  struct timeval tv = { 1, 0 };
  188. +
  189. +  /* Send testing packet */
  190. +  compat_socket_selfpipe_wake( self );
  191. +
  192. +  /* Safe reading from control socket */
  193. +  FD_ZERO( &readfds );
  194. +  FD_SET( self->self_socket, &readfds );
  195. +  active = select( 0, &readfds, NULL, NULL, &tv );
  196. +  if( active == 0 || active == compat_socket_invalid ) {
  197. +    return -1;
  198. +  }
  199. +
  200. +  /* Discard testing packet */
  201. +  if( FD_ISSET( self->self_socket, &readfds ) ) {
  202. +    compat_socket_selfpipe_discard_data( self );
  203. +  }
  204. +
  205. +  return 0;
  206. +}
  207. +
  208.  void
  209.  compat_socket_networking_init( void )
  210.  {
  211. Index: compat/unix/socket.c
  212. ===================================================================
  213. --- compat/unix/socket.c    (revision 4648)
  214. +++ compat/unix/socket.c    (working copy)
  215. @@ -1,4 +1,4 @@
  216. -/* file.c: Socket-related compatibility routines
  217. +/* socket.c: Socket-related compatibility routines
  218.     Copyright (c) 2011 Philip Kendall
  219.  
  220.     $Id$
  221. (c) 2011 Philip Kendall
  222.  
  223.     $Id$