Index: peripherals/nic/w5100_internals.h
===================================================================
--- peripherals/nic/w5100_internals.h (revision 4529)
+++ peripherals/nic/w5100_internals.h (working copy)
@@ -29,6 +29,12 @@
#ifndef FUSE_W5100_INTERNALS_H
#define FUSE_W5100_INTERNALS_H
+#ifdef WIN32
+#include <signal.h>
+
+#define POLLING_INTERVAL 100000
+#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 4529)
+++ peripherals/nic/w5100_socket.c (working copy)
@@ -28,14 +28,19 @@
#include "config.h"
-#include <arpa/inet.h>
-#include <netinet/in.h>
#include <pthread.h>
#include <string.h>
-#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#endif /* #ifdef WIN32 */
+
#include "fuse.h"
#include "ui/ui.h"
#include "w5100.h"
@@ -98,7 +103,7 @@
socket->datagram_count = 0;
if( socket->fd != compat_socket_invalid ) {
- close( socket->fd );
+ compat_socket_close( socket->fd );
socket->fd = compat_socket_invalid;
socket->socket_bound = 0;
socket->ok_for_io = 0;
@@ -172,7 +177,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 );
@@ -183,10 +187,15 @@
return;
}
+#ifndef WIN32
+ int one = 1;
+
+ /* Win32 note: SO_REUSEADDR could be used to forcibly bind sockets already in use */
if( setsockopt( socket_obj->fd, SOL_SOCKET, SO_REUSEADDR, &one,
sizeof(one) ) == -1 ) {
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()));
}
+#endif
socket_obj->state = final_state;
@@ -301,7 +310,7 @@
{
w5100_socket_acquire_lock( socket );
if( socket->fd != compat_socket_invalid ) {
- close( socket->fd );
+ compat_socket_close( socket->fd );
socket->fd = compat_socket_invalid;
socket->socket_bound = 0;
socket->ok_for_io = 0;
@@ -569,7 +578,7 @@
printf("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 )
printf("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 4529)
+++ peripherals/nic/w5100.c (working copy)
@@ -29,12 +29,17 @@
#include "config.h"
#include <errno.h>
-#include <netinet/in.h>
#include <pthread.h>
-#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#include <sys/socket.h>
+#endif /* #ifdef WIN32 */
+
#include "fuse.h"
#include "ui/ui.h"
#include "w5100.h"
@@ -92,17 +97,25 @@
{
nic_w5100_t *self = arg;
int i;
+ fd_set readfds, writefds;
+ int max_fd;
+
+#ifdef WIN32
+ struct timeval tv;
+ fd_set *readfds_p, *writefds_p;
+#endif /* ifdef WIN32 */
while( !self->stop_io_thread ) {
- fd_set readfds, writefds;
int active;
- int max_fd = self->pipe_read;
+ max_fd = -1;
+ FD_ZERO( &readfds );
+ FD_ZERO( &writefds );
- FD_ZERO( &readfds );
+#ifndef WIN32
+ max_fd = self->pipe_read;
FD_SET( self->pipe_read, &readfds );
+#endif /* ifndef WIN32 */
- FD_ZERO( &writefds );
-
for( i = 0; i < 4; i++ )
nic_w5100_socket_add_to_sets( &self->socket[i], &readfds, &writefds,
&max_fd );
@@ -115,25 +128,55 @@
printf("w5100: io thread select\n");
+#ifndef WIN32
active = select( max_fd + 1, &readfds, &writefds, NULL, NULL );
printf("w5100: io thread wake; %d active\n", active);
+#else
+ /* Set max wait time upto 0.1 sec if not IO is completed */
+ tv.tv_sec = 0;
+ tv.tv_usec = POLLING_INTERVAL;
+
+ readfds_p = ( readfds.fd_count )? &readfds : NULL;
+ writefds_p = ( writefds.fd_count )? &writefds : NULL;
+ /* Call select() only if there are pending sockets */
+ if( readfds_p || writefds_p )
+ {
+ active = select( max_fd + 1, readfds_p, writefds_p, NULL, &tv );
+
+ printf("w5100: io thread wake; %d active\n", active);
+ }
+ else {
+ active = 0;
+ usleep( tv.tv_usec );
+ }
+#endif /* ifndef WIN32 */
+
if( active != -1 ) {
+#ifndef WIN32
if( FD_ISSET( self->pipe_read, &readfds ) ) {
char bitbucket;
printf("w5100: discarding pipe data\n");
read( self->pipe_read, &bitbucket, 1 );
}
+#endif /* ifndef WIN32 */
for( i = 0; i < 4; i++ )
nic_w5100_socket_process_io( &self->socket[i], readfds, writefds );
}
- else if( errno == EBADF ) {
+#ifndef WIN32
+ else if( compat_socket_get_error() == EBADF ) {
/* Do nothing - just loop again */
}
+#else
+ else if( compat_socket_get_error() == WSAENOTSOCK ) {
+ /* Do nothing - just loop again */
+ }
+#endif /* ifndef WIN32 */
else {
- printf("w5100: select returned unexpected errno %d: %s\n", errno, strerror(errno));
+ printf("w5100: select returned unexpected errno %d: %s\n",
+ compat_socket_get_error(), strerror(compat_socket_get_error()));
}
}
@@ -143,17 +186,28 @@
void
nic_w5100_wake_io_thread( nic_w5100_t *self )
{
+#ifndef WIN32
const char dummy = 0;
write( self->pipe_write, &dummy, 1 );
+#endif /* ifndef WIN32 */
}
nic_w5100_t*
nic_w5100_alloc( void )
{
int error;
- int pipefd[2];
int i;
+#ifndef WIN32
+ int pipefd[2];
+#endif /* ifndef WIN32 */
+
+ error = compat_networking_init();
+ if( error ) {
+ ui_error( UI_ERROR_ERROR, "Error initializing networking: %d", error );
+ fuse_abort();
+ }
+
nic_w5100_t *self = malloc( sizeof( *self ) );
if( !self ) {
ui_error( UI_ERROR_ERROR, "%s:%d out of memory", __FILE__, __LINE__ );
@@ -165,6 +219,7 @@
nic_w5100_reset( self );
+#ifndef WIN32
error = pipe( pipefd );
if( error ) {
ui_error( UI_ERROR_ERROR, "w5100: error %d creating pipe", error );
@@ -173,6 +228,7 @@
self->pipe_read = pipefd[0];
self->pipe_write = pipefd[1];
+#endif /* ifndef WIN32 */
self->stop_io_thread = 0;
@@ -194,11 +250,18 @@
self->stop_io_thread = 1;
nic_w5100_wake_io_thread( self );
+#ifdef WIN32
+ /* wait IO thread wake up */
+ usleep( 2 * POLLING_INTERVAL );
+#endif /* ifdef WIN32 */
+
pthread_join( self->thread, NULL );
for( i = 0; i < 4; i++ )
nic_w5100_socket_reset( &self->socket[i] );
+ compat_networking_end();
+
free( self );
}
}
Index: configure.in
===================================================================
--- configure.in (revision 4529)
+++ configure.in (working copy)
@@ -110,7 +110,7 @@
AC_MSG_RESULT($win32)
if test "$win32" = yes; then
AC_CHECK_HEADER(windows.h,
- LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread";
+ LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread -lws2_32";
AC_DEFINE([UI_WIN32], 1, [Defined if Win32 UI in use])
AC_DEFINE([WINVER], 0x0400, [Minimal supported version of Windows is 95 or NT4])
AC_DEFINE([_WIN32_IE], 0x400, [Internet Explorer is 4.0 or higher is required])
Index: compat.h
===================================================================
--- compat.h (revision 4529)
+++ compat.h (working copy)
@@ -31,6 +31,10 @@
#include <stdlib.h>
#include <sys/types.h>
+#ifdef WIN32
+#include <winsock2.h>
+#endif /* #ifdef WIN32 */
+
/* Remove the gcc-specific incantations if we're not using gcc */
#ifdef __GNUC__
@@ -129,6 +133,8 @@
extern const compat_socket_t compat_socket_invalid;
+int compat_networking_init( void );
+void compat_networking_end( void );
int compat_socket_close( compat_socket_t fd );
int compat_socket_get_error( void );
Index: compat/win32/socket.c
===================================================================
--- compat/win32/socket.c (revision 4529)
+++ compat/win32/socket.c (working copy)
@@ -32,6 +32,35 @@
const compat_socket_t compat_socket_invalid = INVALID_SOCKET;
int
+compat_networking_init( void )
+{
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int error;
+
+ wVersionRequested = MAKEWORD( 2, 2 );
+ error = WSAStartup( wVersionRequested, &wsaData );
+ if( error ) {
+ return 1;
+ }
+
+ printf("WSAStartup\n");
+ if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
+ WSACleanup();
+ return 2;
+ }
+
+ return 0;
+}
+
+void
+compat_networking_end( void )
+{
+ printf("WSACleanup\n");
+ WSACleanup();
+}
+
+int
compat_socket_close( compat_socket_t fd )
{
return closesocket( fd );
Index: compat/unix/socket.c
===================================================================
--- compat/unix/socket.c (revision 4529)
+++ compat/unix/socket.c (working copy)
@@ -33,6 +33,17 @@
const compat_socket_t compat_socket_invalid = -1;
int
+compat_networking_init( void )
+{
+ return 0;
+}
+
+void
+compat_networking_end( void )
+{
+}
+
+int
compat_socket_close( compat_socket_t fd )
{
return close( fd );