1. Index: peripherals/nic/w5100_internals.h
  2. ===================================================================
  3. --- peripherals/nic/w5100_internals.h   (revision 4529)
  4. +++ peripherals/nic/w5100_internals.h   (working copy)
  5. @@ -29,6 +29,12 @@
  6.  #ifndef FUSE_W5100_INTERNALS_H
  7.  #define FUSE_W5100_INTERNALS_H
  8.  
  9. +#ifdef WIN32
  10. +#include <signal.h>
  11. +
  12. +#define POLLING_INTERVAL 100000
  13. +#endif             /* #ifdef WIN32 */
  14. +
  15.  typedef enum w5100_socket_mode {
  16.    W5100_SOCKET_MODE_CLOSED = 0x00,
  17.    W5100_SOCKET_MODE_TCP,
  18. Index: peripherals/nic/w5100_socket.c
  19. ===================================================================
  20. --- peripherals/nic/w5100_socket.c  (revision 4529)
  21. +++ peripherals/nic/w5100_socket.c  (working copy)
  22. @@ -28,14 +28,19 @@
  23.  
  24.  #include "config.h"
  25.  
  26. -#include <arpa/inet.h>
  27. -#include <netinet/in.h>
  28.  #include <pthread.h>
  29.  #include <string.h>
  30. -#include <sys/socket.h>
  31.  #include <sys/types.h>
  32.  #include <unistd.h>
  33.  
  34. +#ifdef WIN32
  35. +#include <winsock2.h>
  36. +#else
  37. +#include <arpa/inet.h>
  38. +#include <netinet/in.h>
  39. +#include <sys/socket.h>
  40. +#endif             /* #ifdef WIN32 */
  41. +
  42.  #include "fuse.h"
  43.  #include "ui/ui.h"
  44.  #include "w5100.h"
  45. @@ -98,7 +103,7 @@
  46.    socket->datagram_count = 0;
  47.  
  48.    if( socket->fd != compat_socket_invalid ) {
  49. -    close( socket->fd );
  50. +    compat_socket_close( socket->fd );
  51.      socket->fd = compat_socket_invalid;
  52.      socket->socket_bound = 0;
  53.      socket->ok_for_io = 0;
  54. @@ -172,7 +177,6 @@
  55.      int protocol = tcp ? IPPROTO_TCP : IPPROTO_UDP;
  56.      const char *description = tcp ? "TCP" : "UDP";
  57.      int final_state = tcp ? W5100_SOCKET_STATE_INIT : W5100_SOCKET_STATE_UDP;
  58. -    int one = 1;
  59.  
  60.      w5100_socket_clean( socket_obj );
  61.  
  62. @@ -183,10 +187,15 @@
  63.        return;
  64.      }
  65.  
  66. +#ifndef WIN32
  67. +    int one = 1;
  68. +
  69. +    /* Win32 note: SO_REUSEADDR could be used to forcibly bind sockets already in use */
  70.      if( setsockopt( socket_obj->fd, SOL_SOCKET, SO_REUSEADDR, &one,
  71.        sizeof(one) ) == -1 ) {
  72.        printf("w5100: failed to set SO_REUSEADDR on socket %d; errno %d: %s\n", socket_obj->id, compat_socket_get_error(), strerror(compat_socket_get_error()));
  73.      }
  74. +#endif
  75.  
  76.      socket_obj->state = final_state;
  77.  
  78. @@ -301,7 +310,7 @@
  79.  {
  80.    w5100_socket_acquire_lock( socket );
  81.    if( socket->fd != compat_socket_invalid ) {
  82. -    close( socket->fd );
  83. +    compat_socket_close( socket->fd );
  84.      socket->fd = compat_socket_invalid;
  85.      socket->socket_bound = 0;
  86.      socket->ok_for_io = 0;
  87. @@ -569,7 +578,7 @@
  88.  
  89.    printf("w5100: accepted connection from %s:%d on socket %d\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), socket->id);
  90.  
  91. -  if( close( socket->fd ) == -1 )
  92. +  if( compat_socket_close( socket->fd ) == -1 )
  93.      printf("w5100: error attempting to close fd %d for socket %d\n", socket->fd, socket->id);
  94.  
  95.    socket->fd = new_fd;
  96. Index: peripherals/nic/w5100.c
  97. ===================================================================
  98. --- peripherals/nic/w5100.c (revision 4529)
  99. +++ peripherals/nic/w5100.c (working copy)
  100. @@ -29,12 +29,17 @@
  101.  #include "config.h"
  102.  
  103.  #include <errno.h>
  104. -#include <netinet/in.h>
  105.  #include <pthread.h>
  106. -#include <sys/socket.h>
  107.  #include <sys/types.h>
  108.  #include <unistd.h>
  109.  
  110. +#ifdef WIN32
  111. +#include <winsock2.h>
  112. +#else
  113. +#include <netinet/in.h>
  114. +#include <sys/socket.h>
  115. +#endif /* #ifdef WIN32 */
  116. +
  117.  #include "fuse.h"
  118.  #include "ui/ui.h"
  119.  #include "w5100.h"
  120. @@ -92,17 +97,25 @@
  121.  {
  122.    nic_w5100_t *self = arg;
  123.    int i;
  124. +  fd_set readfds, writefds;
  125. +  int max_fd;
  126. +
  127. +#ifdef WIN32
  128. +  struct timeval tv;
  129. +  fd_set *readfds_p, *writefds_p;
  130. +#endif /* ifdef WIN32 */
  131.  
  132.    while( !self->stop_io_thread ) {
  133. -    fd_set readfds, writefds;
  134.      int active;
  135. -    int max_fd = self->pipe_read;
  136. +    max_fd = -1;
  137. +    FD_ZERO( &readfds );
  138. +    FD_ZERO( &writefds );
  139.  
  140. -    FD_ZERO( &readfds );
  141. +#ifndef WIN32
  142. +    max_fd = self->pipe_read;
  143.      FD_SET( self->pipe_read, &readfds );
  144. +#endif /* ifndef WIN32 */
  145.  
  146. -    FD_ZERO( &writefds );
  147. -
  148.      for( i = 0; i < 4; i++ )
  149.        nic_w5100_socket_add_to_sets( &self->socket[i], &readfds, &writefds,
  150.          &max_fd );
  151. @@ -115,25 +128,55 @@
  152.  
  153.      printf("w5100: io thread select\n");
  154.  
  155. +#ifndef WIN32
  156.      active = select( max_fd + 1, &readfds, &writefds, NULL, NULL );
  157.  
  158.      printf("w5100: io thread wake; %d active\n", active);
  159. +#else
  160. +    /* Set max wait time upto 0.1 sec if not IO is completed */
  161. +    tv.tv_sec = 0;
  162. +    tv.tv_usec = POLLING_INTERVAL;
  163. +
  164. +    readfds_p = ( readfds.fd_count )? &readfds : NULL;
  165. +    writefds_p = ( writefds.fd_count )? &writefds : NULL;
  166.  
  167. +    /* Call select() only if there are pending sockets */
  168. +    if( readfds_p || writefds_p )
  169. +    {
  170. +      active = select( max_fd + 1, readfds_p, writefds_p, NULL, &tv );
  171. +
  172. +      printf("w5100: io thread wake; %d active\n", active);
  173. +    }
  174. +    else {
  175. +      active = 0;
  176. +      usleep( tv.tv_usec );
  177. +    }
  178. +#endif /* ifndef WIN32 */
  179. +
  180.      if( active != -1 ) {
  181. +#ifndef WIN32
  182.        if( FD_ISSET( self->pipe_read, &readfds ) ) {
  183.          char bitbucket;
  184.          printf("w5100: discarding pipe data\n");
  185.          read( self->pipe_read, &bitbucket, 1 );
  186.        }
  187. +#endif /* ifndef WIN32 */
  188.  
  189.        for( i = 0; i < 4; i++ )
  190.          nic_w5100_socket_process_io( &self->socket[i], readfds, writefds );
  191.      }
  192. -    else if( errno == EBADF ) {
  193. +#ifndef WIN32
  194. +    else if( compat_socket_get_error() == EBADF ) {
  195.        /* Do nothing - just loop again */
  196.      }
  197. +#else
  198. +    else if( compat_socket_get_error() == WSAENOTSOCK ) {
  199. +      /* Do nothing - just loop again */
  200. +    }
  201. +#endif /* ifndef WIN32 */
  202.      else {
  203. -      printf("w5100: select returned unexpected errno %d: %s\n", errno, strerror(errno));
  204. +      printf("w5100: select returned unexpected errno %d: %s\n",
  205. +             compat_socket_get_error(), strerror(compat_socket_get_error()));
  206.      }
  207.    }
  208.  
  209. @@ -143,17 +186,28 @@
  210.  void
  211.  nic_w5100_wake_io_thread( nic_w5100_t *self )
  212.  {
  213. +#ifndef WIN32
  214.    const char dummy = 0;
  215.    write( self->pipe_write, &dummy, 1 );
  216. +#endif /* ifndef WIN32 */
  217.  }
  218.  
  219.  nic_w5100_t*
  220.  nic_w5100_alloc( void )
  221.  {
  222.    int error;
  223. -  int pipefd[2];
  224.    int i;
  225.  
  226. +#ifndef WIN32
  227. +  int pipefd[2];
  228. +#endif /* ifndef WIN32 */
  229. +
  230. +  error = compat_networking_init();
  231. +  if( error ) {
  232. +    ui_error( UI_ERROR_ERROR, "Error initializing networking: %d", error );
  233. +    fuse_abort();
  234. +  }
  235. +
  236.    nic_w5100_t *self = malloc( sizeof( *self ) );
  237.    if( !self ) {
  238.      ui_error( UI_ERROR_ERROR, "%s:%d out of memory", __FILE__, __LINE__ );
  239. @@ -165,6 +219,7 @@
  240.  
  241.    nic_w5100_reset( self );
  242.  
  243. +#ifndef WIN32
  244.    error = pipe( pipefd );
  245.    if( error ) {
  246.      ui_error( UI_ERROR_ERROR, "w5100: error %d creating pipe", error );
  247. @@ -173,6 +228,7 @@
  248.  
  249.    self->pipe_read = pipefd[0];
  250.    self->pipe_write = pipefd[1];
  251. +#endif /* ifndef WIN32 */
  252.  
  253.    self->stop_io_thread = 0;
  254.  
  255. @@ -194,11 +250,18 @@
  256.      self->stop_io_thread = 1;
  257.      nic_w5100_wake_io_thread( self );
  258.  
  259. +#ifdef WIN32
  260. +    /* wait IO thread wake up */
  261. +    usleep( 2 * POLLING_INTERVAL );
  262. +#endif /* ifdef WIN32 */
  263. +
  264.      pthread_join( self->thread, NULL );
  265.  
  266.      for( i = 0; i < 4; i++ )
  267.        nic_w5100_socket_reset( &self->socket[i] );
  268.  
  269. +    compat_networking_end();
  270. +
  271.      free( self );
  272.    }
  273.  }
  274. Index: configure.in
  275. ===================================================================
  276. --- configure.in    (revision 4529)
  277. +++ configure.in    (working copy)
  278. @@ -110,7 +110,7 @@
  279.  AC_MSG_RESULT($win32)
  280.  if test "$win32" = yes; then
  281.    AC_CHECK_HEADER(windows.h,
  282. -                  LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread";
  283. +                  LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread -lws2_32";
  284.                    AC_DEFINE([UI_WIN32], 1, [Defined if Win32 UI in use])
  285.                    AC_DEFINE([WINVER], 0x0400, [Minimal supported version of Windows is 95 or NT4])
  286.                    AC_DEFINE([_WIN32_IE], 0x400, [Internet Explorer is 4.0 or higher is required])
  287. Index: compat.h
  288. ===================================================================
  289. --- compat.h    (revision 4529)
  290. +++ compat.h    (working copy)
  291. @@ -31,6 +31,10 @@
  292.  #include <stdlib.h>
  293.  #include <sys/types.h>
  294.  
  295. +#ifdef WIN32
  296. +#include <winsock2.h>
  297. +#endif             /* #ifdef WIN32 */
  298. +
  299.  /* Remove the gcc-specific incantations if we're not using gcc */
  300.  #ifdef __GNUC__
  301.  
  302. @@ -129,6 +133,8 @@
  303.  
  304.  extern const compat_socket_t compat_socket_invalid;
  305.  
  306. +int compat_networking_init( void );
  307. +void compat_networking_end( void );
  308.  int compat_socket_close( compat_socket_t fd );
  309.  int compat_socket_get_error( void );
  310.  
  311. Index: compat/win32/socket.c
  312. ===================================================================
  313. --- compat/win32/socket.c   (revision 4529)
  314. +++ compat/win32/socket.c   (working copy)
  315. @@ -32,6 +32,35 @@
  316.  const compat_socket_t compat_socket_invalid = INVALID_SOCKET;
  317.  
  318.  int
  319. +compat_networking_init( void )
  320. +{
  321. +  WORD wVersionRequested;
  322. +  WSADATA wsaData;
  323. +  int error;
  324. +
  325. +  wVersionRequested = MAKEWORD( 2, 2 );
  326. +  error = WSAStartup( wVersionRequested, &wsaData );
  327. +  if( error ) {
  328. +    return 1;
  329. +  }
  330. +
  331. +  printf("WSAStartup\n");
  332. +  if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
  333. +    WSACleanup();
  334. +    return 2;
  335. +  }
  336. +
  337. +  return 0;
  338. +}
  339. +
  340. +void
  341. +compat_networking_end( void )
  342. +{
  343. +  printf("WSACleanup\n");
  344. +  WSACleanup();
  345. +}
  346. +
  347. +int
  348.  compat_socket_close( compat_socket_t fd )
  349.  {
  350.    return closesocket( fd );
  351. Index: compat/unix/socket.c
  352. ===================================================================
  353. --- compat/unix/socket.c    (revision 4529)
  354. +++ compat/unix/socket.c    (working copy)
  355. @@ -33,6 +33,17 @@
  356.  const compat_socket_t compat_socket_invalid = -1;
  357.  
  358.  int
  359. +compat_networking_init( void )
  360. +{
  361. +  return 0;
  362. +}
  363. +
  364. +void
  365. +compat_networking_end( void )
  366. +{
  367. +}
  368. +
  369. +int
  370.  compat_socket_close( compat_socket_t fd )
  371.  {
  372.    return close( fd );