Index: peripherals/nic/w5100_internals.h
===================================================================
--- peripherals/nic/w5100_internals.h (revision 4494)
+++ peripherals/nic/w5100_internals.h (working copy)
@@ -29,6 +29,19 @@
#ifndef FUSE_W5100_INTERNALS_H
#define FUSE_W5100_INTERNALS_H
+#ifdef WIN32
+#include <signal.h>
+#endif /* #ifdef WIN32 */
+
+#ifdef WIN32
+#define close_socket( x ) closesocket( x )
+typedef SOCKET socket_t;
+#else
+#define INVALID_SOCKET -1
+#define close_socket( x ) close( x )
+typedef int socket_t;
+#endif /* #ifdef WIN32 */
+
typedef enum w5100_socket_mode {
W5100_SOCKET_MODE_CLOSED = 0x00,
W5100_SOCKET_MODE_TCP,
@@ -105,7 +118,7 @@
/* Host properties */
- int fd; /* Socket file descriptor */
+ socket_t fd; /* Socket file descriptor */
int write_pending; /* True if we're waiting to write data on this socket */
/* Flag used to indicate that a socket has been closed since we started
@@ -126,6 +139,10 @@
nic_w5100_socket_t socket[4];
+#ifdef WIN32
+ nic_w5100_socket_t dummy_socket;
+#endif
+
pthread_t thread; /* Thread for doing I/O */
sig_atomic_t stop_io_thread; /* Flag to stop I/O thread */
int pipe_read; /* Pipe for waking I/O thread */
@@ -136,6 +153,9 @@
void nic_w5100_socket_init( nic_w5100_socket_t *socket, int which );
void nic_w5100_socket_free( nic_w5100_socket_t *socket );
+#ifdef WIN32
+void nic_w5100_open_control_socket( nic_w5100_socket_t *socket );
+#endif
void nic_w5100_socket_reset( nic_w5100_socket_t *socket );
Index: peripherals/nic/w5100_socket.c
===================================================================
--- peripherals/nic/w5100_socket.c (revision 4494)
+++ peripherals/nic/w5100_socket.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"
@@ -51,7 +56,7 @@
nic_w5100_socket_init( nic_w5100_socket_t *socket, int which )
{
socket->id = which;
- socket->fd = -1;
+ socket->fd = INVALID_SOCKET;
socket->ok_for_io = 0;
pthread_mutex_init( &socket->lock, NULL );
}
@@ -105,10 +110,11 @@
void
nic_w5100_socket_free( nic_w5100_socket_t *socket )
{
- if( socket->fd != -1 ) {
+ if( socket->fd != INVALID_SOCKET ) {
+ printf( "nic_w5100_socket_free %d\n", socket->id );
w5100_socket_acquire_lock( socket );
- close( socket->fd );
- socket->fd = -1;
+ close_socket( socket->fd );
+ socket->fd = INVALID_SOCKET;
socket->ok_for_io = 0;
socket->write_pending = 0;
w5100_socket_release_lock( socket );
@@ -162,7 +168,7 @@
w5100_socket_acquire_lock( socket_obj );
socket_obj->fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
- if( socket_obj->fd == -1 ) {
+ if( socket_obj->fd == INVALID_SOCKET ) {
printf("w5100: failed to open UDP socket for socket %d; errno = %d\n", socket_obj->id, errno);
w5100_socket_release_lock( socket_obj );
return;
@@ -178,7 +184,7 @@
w5100_socket_acquire_lock( socket_obj );
socket_obj->fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
- if( socket_obj->fd == -1 ) {
+ if( socket_obj->fd == INVALID_SOCKET ) {
printf("w5100: failed to open TCP socket for socket %d; errno = %d\n", socket_obj->id, errno);
w5100_socket_release_lock( socket_obj );
return;
@@ -218,8 +224,8 @@
if( socket->mode == W5100_SOCKET_MODE_UDP &&
socket->state == W5100_SOCKET_STATE_UDP ) {
w5100_socket_acquire_lock( socket );
- close( socket->fd );
- socket->fd = -1;
+ close_socket( socket->fd );
+ socket->fd = INVALID_SOCKET;
socket->ok_for_io = 0;
socket->state = W5100_SOCKET_STATE_CLOSED;
w5100_socket_release_lock( socket );
@@ -334,6 +340,7 @@
printf("w5100: reading 0x%02x from unsupported register 0x%03x\n", b, reg );
break;
}
+
return b;
}
@@ -414,7 +421,7 @@
{
w5100_socket_acquire_lock( socket );
- if( socket->fd != -1 ) {
+ if( socket->fd != INVALID_SOCKET ) {
socket->ok_for_io = 1;
/* We can process a UDP read if we're in a UDP state and there are at least
@@ -455,7 +462,7 @@
sa.sin_family = AF_INET;
memcpy( &sa.sin_port, socket->port, 2 );
sa.sin_addr.s_addr = htonl(INADDR_ANY);
- bytes_read = recvfrom( socket->fd, buffer + 8, bytes_free - 8, 0, (struct sockaddr*)&sa, &sa_length );
+ bytes_read = recvfrom( socket->fd, (char *)buffer + 8, bytes_free - 8, 0, (struct sockaddr*)&sa, &sa_length );
printf("w5100: read 0x%03x bytes from socket %d\n", (int)bytes_read, socket->id);
if( bytes_read != -1 ) {
@@ -506,7 +513,7 @@
memcpy( &sa.sin_port, socket->dport, 2 );
memcpy( &sa.sin_addr.s_addr, socket->dip, 4 );
- bytes_sent = sendto( socket->fd, data, length, 0, (struct sockaddr*)&sa, sizeof(sa) );
+ bytes_sent = sendto( socket->fd, (const char *)data, length, 0, (struct sockaddr*)&sa, sizeof(sa) );
printf("w5100: sent 0x%03x bytes of %d to socket %d\n", (int)bytes_sent, length, socket->id);
if( bytes_sent != -1 ) {
@@ -528,7 +535,7 @@
/* Process only if we're an open socket, and we haven't been closed and
re-opened since the select() started */
- if( socket->fd != -1 && socket->ok_for_io ) {
+ if( socket->fd != INVALID_SOCKET && socket->ok_for_io ) {
if( FD_ISSET( socket->fd, &readfds ) )
w5100_socket_process_read( socket );
@@ -538,3 +545,12 @@
w5100_socket_release_lock( socket );
}
+
+#ifdef WIN32
+void
+nic_w5100_open_control_socket( nic_w5100_socket_t *socket )
+{
+ socket->mode = W5100_SOCKET_MODE_UDP;
+ w5100_socket_open( socket );
+}
+#endif
\ No newline at end of file
Index: peripherals/nic/w5100.c
===================================================================
--- peripherals/nic/w5100.c (revision 4494)
+++ 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"
@@ -91,32 +96,57 @@
w5100_io_thread( void *arg )
{
nic_w5100_t *self = arg;
- int i;
+ int i, retval;
+ struct timeval *tvp = NULL;
+#ifdef WIN32
+ struct timeval tv;
+ tvp = &tv;
+#endif
+
while( !self->stop_io_thread ) {
fd_set readfds, writefds;
- int max_fd = self->pipe_read;
+ int max_fd = -1;
FD_ZERO( &readfds );
+ FD_ZERO( &writefds );
+
+#ifndef WIN32
+ max_fd = self->pipe_read;
FD_SET( self->pipe_read, &readfds );
+#else
+ nic_w5100_socket_add_to_sets( &self->dummy_socket, &readfds, &writefds,
+ &max_fd );
- FD_ZERO( &writefds );
+ tv.tv_sec = 1; /* wait 1 second max */
+ tv.tv_usec = 0;
+#endif
for( i = 0; i < 4; i++ )
nic_w5100_socket_add_to_sets( &self->socket[i], &readfds, &writefds,
&max_fd );
printf("w5100: io thread select\n");
+ retval = select( max_fd + 1, &readfds, &writefds, NULL, tvp );
+ if( retval < 0 ) {
+#ifdef WIN32
+ printf( "w5100: io thread wake from select with error %d\n",
+ WSAGetLastError() );
+#else
+ printf( "w5100: io thread wake from select with error %d\n",
+ retval );
+#endif
+ }
- select( max_fd + 1, &readfds, &writefds, NULL, NULL );
+ printf("w5100: io thread wake from select %d\n", retval);
- printf("w5100: io thread wake\n");
-
+#ifndef WIN32
if( FD_ISSET( self->pipe_read, &readfds ) ) {
char bitbucket;
printf("w5100: discarding pipe data\n");
read( self->pipe_read, &bitbucket, 1 );
}
+#endif
for( i = 0; i < 4; i++ )
nic_w5100_socket_process_io( &self->socket[i], readfds, writefds );
@@ -128,28 +158,54 @@
void
nic_w5100_wake_io_thread( nic_w5100_t *self )
{
+#ifndef WIN32
const char dummy = 0;
write( self->pipe_write, &dummy, 1 );
+#endif
}
nic_w5100_t*
nic_w5100_alloc( void )
{
int error;
- int pipefd[2];
int i;
+#ifndef WIN32
+ int pipefd[2];
+#else
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD( 2, 2 );
+ error = WSAStartup( wVersionRequested, &wsaData );
+ if( error ) {
+ ui_error( UI_ERROR_ERROR, "WSAStartup failed with error: %d", error );
+ fuse_abort();
+ }
+
+ if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
+ WSACleanup();
+ ui_error( UI_ERROR_ERROR, "FUSE could not find a usable Winsock DLL" );
+ fuse_abort();
+ }
+#endif /* ifndef WIN32 */
+
nic_w5100_t *self = malloc( sizeof( *self ) );
if( !self ) {
ui_error( UI_ERROR_ERROR, "%s:%d out of memory", __FILE__, __LINE__ );
fuse_abort();
}
+#ifdef WIN32
+ nic_w5100_socket_init( &self->dummy_socket, -1 );
+#endif /* ifdef WIN32 */
+
for( i = 0; i < 4; i++ )
nic_w5100_socket_init( &self->socket[i], i );
w5100_reset( self );
+#ifndef WIN32
error = pipe( pipefd );
if( error ) {
ui_error( UI_ERROR_ERROR, "w5100: error %d creating pipe", error );
@@ -158,6 +214,10 @@
self->pipe_read = pipefd[0];
self->pipe_write = pipefd[1];
+#else
+ /* open dummy socket to allow SELECT model */
+ nic_w5100_open_control_socket( &self->dummy_socket );
+#endif
self->stop_io_thread = 0;
@@ -182,7 +242,12 @@
for( i = 0; i < 4; i++ )
nic_w5100_socket_free( &self->socket[i] );
-
+
+#ifdef WIN32
+ nic_w5100_socket_free( &self->dummy_socket );
+ WSACleanup();
+#endif
+
free( self );
}
Index: configure.in
===================================================================
--- configure.in (revision 4494)
+++ 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";
+ LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread";
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: ui/win32/win32ui.c
===================================================================
--- ui/win32/win32ui.c (revision 4494)
+++ ui/win32/win32ui.c (working copy)
@@ -24,6 +24,7 @@
*/
#include <config.h>
+#include <fcntl.h>
#include <tchar.h>
#include "debugger/debugger.h"
@@ -277,6 +278,46 @@
return( DefWindowProc( hWnd, msg, wParam, lParam ) );
}
+void redirect_IO_to_console( void )
+{
+ int hConHandle;
+ HANDLE std_handle;
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+ FILE *fp;
+
+ /* allocate a console for this app */
+ AllocConsole();
+
+ /* set the screen buffer to be big enough to let us scroll text */
+ std_handle = GetStdHandle( STD_OUTPUT_HANDLE );
+ if( !std_handle || std_handle == INVALID_HANDLE_VALUE ) return;
+ GetConsoleScreenBufferInfo( std_handle, &coninfo );
+ coninfo.dwSize.Y = 500;
+ SetConsoleScreenBufferSize( std_handle, coninfo.dwSize );
+
+ /* redirect unbuffered STDOUT to the console */
+ hConHandle = _open_osfhandle( (intptr_t)std_handle, _O_TEXT );
+ fp = _fdopen( hConHandle, "w" );
+ *stdout = *fp;
+ setvbuf( stdout, NULL, _IONBF, 0 );
+
+ /* redirect unbuffered STDIN to the console */
+ std_handle = GetStdHandle( STD_INPUT_HANDLE );
+ if( !std_handle || std_handle == INVALID_HANDLE_VALUE ) return;
+ hConHandle = _open_osfhandle( (intptr_t)std_handle, _O_TEXT );
+ fp = _fdopen( hConHandle, "r" );
+ *stdin = *fp;
+ setvbuf( stdin, NULL, _IONBF, 0 );
+
+ /* redirect unbuffered STDERR to the console */
+ std_handle = GetStdHandle( STD_ERROR_HANDLE );
+ if( !std_handle || std_handle == INVALID_HANDLE_VALUE ) return;
+ hConHandle = _open_osfhandle( (intptr_t)std_handle, _O_TEXT );
+ fp = _fdopen( hConHandle, "w" );
+ *stderr = *fp;
+ setvbuf( stderr, NULL, _IONBF, 0 );
+}
+
/* this is where windows program begins */
int WINAPI
WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
@@ -287,6 +328,10 @@
fuse_nCmdShow = nCmdShow;
fuse_hPrevInstance = hPrevInstance;
+#ifdef _DEBUG
+ redirect_IO_to_console();
+#endif
+
return fuse_main(__argc, __argv);
/* FIXME: how do deal with returning wParam */
}