Release 970928
Sat Sep 27 12:36:56 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [if1632/relay.c]
Made Catch and Throw also save %si and %di (untested).
* [memory/selector.c]
Added check for %fs and %gs in SELECTOR_FreeBlock.
* [rc/winerc.c]
Generated files no longer depend on Wine includes.
Made .h generation optional.
* [tools/build.c] [loader/task.c]
Added CALL32_Init function.
Added possibility to pass arguments when using CALLTO16_regs_.
32-bit stack pointer is now saved on the 16-bit stack, instead of
using IF1632_Saved32_esp.
Removed CallTo32 callbacks.
* [tools/makedep.c] [*/Makefile.in]
Added support for directly generating dependencies for .y, .l and
.rc files. Modified the makefiles to use this feature.
* [windows/winproc.c] [if1632/thunk.c]
Use CALLTO16_regs to call window procedures.
Thu Sep 25 12:18:57 1997 Kristian Nielsen <kristian.nielsen@risoe.dk>
* [if1632/kernel.spec]
Changed entry for SwitchStackBack to remove arguments from stack
upon return (arguments left over from previous SwitchStackTo()).
Borland C++ 4.0 now compiles "Hello World" (but crashes after
outputting the .exe).
Wed Sep 24 13:54:44 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [files/directory.c]
SearchPath might get NULL buffer (empty LRU list in wordpad).
* [memory/selector.c]
Added SUnMapLS*.
* [loader/pe_image.c]
Be able to run executeables from non mmap()ble filesystems.
PE_LoadLibrary adds librarys loaded by another process to
its own modref list too.
* [windows/keyboard.c][include/accel.h][loader/resource.c]
Fixed accelerator leakage, use SDK defines/names.
* [graphics/env.c][misc/main.c]
Set/GetEnvironemnt have nothing to do with environment vars,
but with Printer Environment.
* [graphics/escape.c]
Escape32: map args back to segmented pointers.
* [windows/win.c]
WS_POPUP|WS_CHILD windows don't need a parent window (SDK).
Tue Sep 16 14:40:16 1997 Robert Wilhelm <robert@physiol.med.tu-muenchen.de>
* [if1632/crtdll.spec] [misc/crtdll.c]
Added signal().
diff --git a/misc/winsock.c b/misc/winsock.c
index bec016c..c4d8d3d 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -43,6 +43,7 @@
#include "stddebug.h"
#include "debug.h"
+#define DEBUG_SOCKADDR 0
#define dump_sockaddr(a) \
fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
((struct sockaddr_in *)a)->sin_family, \
@@ -147,16 +148,16 @@
return NULL;
}
-static void fd_set_normalize(fd_set* fds, LPWSINFO pwsi, ws_fd_set* ws, int* highfd)
+static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, ws_fd_set* ws, int* highfd )
{
- /* translate Winsock fd set into the normal fd set */
+ /* translate Winsock fd set into local fd set */
- FD_ZERO(fds);
if( ws )
{
int i;
ws_socket* pws;
+ FD_ZERO(fds);
for( i = 0; i < (ws->fd_count) ; i++ )
{
pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
@@ -166,29 +167,28 @@
FD_SET(pws->fd, fds);
}
}
+ return fds;
}
+ return NULL;
}
-/*
- * Note weirdness here: sockets with errors belong in exceptfds, but
- * are given to us in readfds or writefds, so move them to exceptfds if
- * there is an error. Note that this means that exceptfds may have mysterious
- * sockets set in it that the program never asked for.
- */
-
__inline__ static int sock_error_p(int s)
{
unsigned int optval, optlen;
optlen = sizeof(optval);
getsockopt(s, SOL_SOCKET, SO_ERROR, &optval, &optlen);
- if (optval) dprintf_winsock(stddeb, "error: %d\n", optval);
+ if (optval) dprintf_winsock(stddeb, "\t[%i] error: %d\n", s, optval);
return optval != 0;
}
-static void fd_set_update(LPWSINFO pwsi, fd_set* fds, ws_fd_set* ws,
- fd_set *errorfds)
+static int fd_set_export( LPWSINFO pwsi, fd_set* fds, fd_set* exceptfds, ws_fd_set* ws )
{
+ int num_err = 0;
+
+ /* translate local fd set into Winsock fd set, adding
+ * errors to exceptfds (only if app requested it) */
+
if( ws )
{
int i, j, count = ws->fd_count;
@@ -200,9 +200,11 @@
if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
{
- /* if error, move to errorfds */
- if (errorfds && (FD_ISSET(fd, errorfds) || sock_error_p(fd)))
- FD_SET(fd, errorfds);
+ if ( exceptfds && sock_error_p(fd) )
+ {
+ FD_SET(fd, exceptfds);
+ num_err++;
+ }
else
ws->fd_array[j++] = ws->fd_array[i];
}
@@ -210,7 +212,7 @@
ws->fd_count = j;
dprintf_winsock(stddeb, "\n");
}
- return;
+ return num_err;
}
HANDLE16 __ws_gethandle( void* ptr )
@@ -520,9 +522,9 @@
SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, struct sockaddr* addr,
INT16* addrlen16 )
{
- INT32 addrlen32 = *addrlen16;
+ INT32 addrlen32 = addrlen16 ? *addrlen16 : 0;
SOCKET32 retSocket = WINSOCK_accept32( s, addr, &addrlen32 );
- *addrlen16 = (INT16)addrlen32;
+ if( addrlen16 ) *addrlen16 = (INT16)addrlen32;
return (SOCKET16)retSocket;
}
@@ -536,7 +538,7 @@
dprintf_winsock(stddeb, "WS_BIND(%08x): socket %04x, ptr %8x, length %d\n",
(unsigned)pwsi, s, (int) name, namelen);
-#if 0
+#if DEBUG_SOCKADDR
dump_sockaddr(name);
#endif
@@ -614,7 +616,7 @@
dprintf_winsock(stddeb, "WS_CONNECT(%08x): socket %04x, ptr %8x, length %d\n",
(unsigned)pwsi, s, (int) name, namelen);
-#if 0
+#if DEBUG_SOCKADDR
dump_sockaddr(name);
#endif
@@ -622,9 +624,13 @@
{
if (connect(pws->fd, name, namelen) == 0)
{
- pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT);
- if( pws->psop && pws->flags & WS_FD_CONNECT )
+ if( pws->psop && (pws->flags & WS_FD_CONNECT) )
{
+ /* application did AsyncSelect() but then went
+ * ahead and called connect() without waiting for
+ * notification.
+ */
+
if( !(pws->flags & WS_FD_CONNECTED) )
{
if( pws->flags & (WS_FD_READ | WS_FD_CLOSE) )
@@ -638,6 +644,7 @@
pws->flags |= WS_FD_CONNECTED;
}
}
+ pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT);
return 0;
}
pwsi->err = (errno == EINPROGRESS) ? WSAEWOULDBLOCK : wsaErrno();
@@ -682,7 +689,7 @@
INT32 namelen32 = *namelen16;
INT32 retVal = WINSOCK_getpeername32( s, name, &namelen32 );
-#if 0
+#if DEBUG_SOCKADDR
dump_sockaddr(name);
#endif
@@ -716,9 +723,20 @@
INT16 WINAPI WINSOCK_getsockname16(SOCKET16 s, struct sockaddr *name,
INT16 *namelen16)
{
- INT32 namelen32 = *namelen16;
- INT32 retVal = WINSOCK_getsockname32( s, name, &namelen32 );
- *namelen16 = namelen32;
+ INT32 retVal;
+
+ if( namelen16 )
+ {
+ INT32 namelen32 = *namelen16;
+ retVal = WINSOCK_getsockname32( s, name, &namelen32 );
+ *namelen16 = namelen32;
+
+#if DEBUG_SOCKADDR
+ dump_sockaddr(name);
+#endif
+
+ }
+ else retVal = SOCKET_ERROR;
return (INT16)retVal;
}
@@ -750,9 +768,12 @@
INT16 WINAPI WINSOCK_getsockopt16(SOCKET16 s, INT16 level,
INT16 optname, char *optval, INT16 *optlen)
{
- INT32 optlen32 = *optlen;
- INT32 retVal = WINSOCK_getsockopt32( s, level, optname, optval, &optlen32 );
- *optlen = optlen32;
+ INT32 optlen32;
+ INT32 *p = &optlen32;
+ INT32 retVal;
+ if( optlen ) optlen32 = *optlen; else p = NULL;
+ retVal = WINSOCK_getsockopt32( s, level, optname, optval, p );
+ if( optlen ) *optlen = optlen32;
return (INT16)retVal;
}
@@ -883,6 +904,7 @@
int fd_flags = fcntl(pws->fd, F_GETFL, 0);
if( !(fd_flags & O_NONBLOCK) ) pws->flags |= WS_FD_ACCEPT;
}
+ else if( !(pws->flags & WS_FD_CONNECTED) ) pws->flags |= WS_FD_LISTENING;
if (listen(pws->fd, backlog) == 0) return 0;
pwsi->err = wsaErrno();
@@ -949,6 +971,11 @@
dprintf_winsock(stddeb, "WS_RECVFROM(%08x): socket %04x, ptr %08x, len %d, flags %d",
(unsigned)pwsi, s, (unsigned)buf, len, flags);
+#if DEBUG_SOCKADDR
+ if( from ) dump_sockaddr(from);
+ else fprintf(stderr, "\tfrom = NULL\n");
+#endif
+
if( _check_ws(pwsi, pws) )
{
int length;
@@ -975,9 +1002,13 @@
INT16 WINAPI WINSOCK_recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
struct sockaddr *from, INT16 *fromlen16)
{
- INT32 fromlen32 = *fromlen16;
- INT32 retVal = WINSOCK_recvfrom32( s, buf, len, flags, from, &fromlen32 );
- *fromlen16 = fromlen32;
+ INT32 fromlen32;
+ INT32 *p = &fromlen32;
+ INT32 retVal;
+
+ if( fromlen16 ) fromlen32 = *fromlen16; else p = NULL;
+ retVal = WINSOCK_recvfrom32( s, buf, len, flags, from, p );
+ if( fromlen16 ) *fromlen16 = fromlen32;
return (INT16)retVal;
}
@@ -988,50 +1019,46 @@
ws_fd_set *ws_writefds, ws_fd_set *ws_exceptfds,
struct timeval *timeout)
{
- LPWSINFO pwsi = wsi_find(GetCurrentTask());
+ LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_SELECT(%08x): nfds %d (ignored), read %8x, write %8x, excp %8x\n",
- (unsigned) pwsi, nfds, (unsigned) ws_readfds, (unsigned) ws_writefds, (unsigned) ws_exceptfds);
+ dprintf_winsock(stddeb, "WS_SELECT(%08x): nfds %d (ignored), read %8x, write %8x, excp %8x\n",
+ (unsigned) pwsi, nfds, (unsigned) ws_readfds, (unsigned) ws_writefds, (unsigned) ws_exceptfds);
- if( pwsi )
- {
- int highfd = 0;
- fd_set readfds, writefds, exceptfds, errorfds;
+ if( pwsi )
+ {
+ int highfd = 0;
+ fd_set readfds, writefds, exceptfds;
+ fd_set *p_read, *p_write, *p_except;
- fd_set_normalize(&readfds, pwsi, ws_readfds, &highfd);
- fd_set_normalize(&writefds, pwsi, ws_writefds, &highfd);
- fd_set_normalize(&exceptfds, pwsi, ws_exceptfds, &highfd);
- FD_ZERO(&errorfds);
+ p_read = fd_set_import(&readfds, pwsi, ws_readfds, &highfd);
+ p_write = fd_set_import(&writefds, pwsi, ws_writefds, &highfd);
+ p_except = fd_set_import(&exceptfds, pwsi, ws_exceptfds, &highfd);
- if( (highfd = select(highfd + 1, &readfds, &writefds, &exceptfds, timeout)) >= 0 )
- {
- if( highfd )
- {
- fd_set_update(pwsi, &readfds, ws_readfds, &errorfds);
- fd_set_update(pwsi, &writefds, ws_writefds, &errorfds);
-
- /* update exception set (see "weirdness" comment in the
- * beginning of the file). */
-
- if (ws_exceptfds)
+ if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) >= 0 )
+ {
+ if( highfd )
{
- int i, j, count = ws_exceptfds->fd_count;
+ fd_set_export(pwsi, &readfds, p_except, ws_readfds);
+ fd_set_export(pwsi, &writefds, p_except, ws_writefds);
- for (i = j = 0; i < count; i++)
+ if (p_except && ws_exceptfds)
{
- ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws_exceptfds->fd_array[i]);
- if( _check_ws(pwsi, pws) &&
- (FD_ISSET(pws->fd, &exceptfds) || FD_ISSET(pws->fd, &errorfds)) )
- ws_exceptfds->fd_array[j++] = ws_exceptfds->fd_array[i];
+ int i, j, count = ws_exceptfds->fd_count;
+
+ for (i = j = 0; i < count; i++)
+ {
+ ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws_exceptfds->fd_array[i]);
+ if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
+ ws_exceptfds->fd_array[j++] = ws_exceptfds->fd_array[i];
+ }
+ ws_exceptfds->fd_count = j;
}
- ws_exceptfds->fd_count = j;
}
- }
- return highfd;
- }
- pwsi->err = wsaErrno();
- }
- return SOCKET_ERROR;
+ return highfd;
+ }
+ pwsi->err = wsaErrno();
+ }
+ return SOCKET_ERROR;
}
/***********************************************************************
@@ -1146,6 +1173,7 @@
char *optval, INT16 optlen)
{
INT32 linger32[2];
+ if( !optval ) return SOCKET_ERROR;
if( optname == SO_LINGER )
{
INT16* ptr = (INT16*)optval;
@@ -1195,7 +1223,7 @@
{
if( how > 1 )
{
- pws->flags &= ~WS_FD_CONNECTED;
+ pws->flags &= ~(WS_FD_CONNECTED | WS_FD_LISTENING);
pws->flags |= WS_FD_INACTIVE;
}
return 0;
@@ -1780,10 +1808,14 @@
num_pending--;
- if( flags & WS_FD_ACCEPT )
- {
- /* listening socket */
+ /* Now figure out what kind of event we've got. The worst problem
+ * we have to contend with is that some out of control applications
+ * really want to use mutually exclusive AsyncSelect() flags all at
+ * the same time.
+ */
+ if((flags & WS_FD_ACCEPT) && (flags & WS_FD_LISTENING))
+ {
FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
if( r )
{
@@ -1807,8 +1839,12 @@
if( flags & (WS_FD_READ | WS_FD_CLOSE))
FD_SET( fd, &io_set[EVENT_IO_READ] );
- if( flags & WS_FD_WRITE ) FD_SET( fd, &io_set[EVENT_IO_WRITE] );
- else FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+ else
+ FD_CLR( fd, &io_set[EVENT_IO_READ] );
+ if( flags & WS_FD_WRITE )
+ FD_SET( fd, &io_set[EVENT_IO_WRITE] );
+ else
+ FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
bPost = TRUE;
}
else if( r )
@@ -1838,6 +1874,8 @@
if( PostMessage16( psop->hWnd, psop->uMsg, (WPARAM16)WS_PTR2HANDLE(psop->pws),
(LPARAM)WSAMAKESELECTREPLY( WS_FD_WRITE, 0 ) ) )
{
+ dprintf_winsock(stddeb, "\t hwnd %04x - %04x, %08x\n",
+ psop->hWnd, psop->uMsg, (unsigned)MAKELONG(WS_FD_WRITE, 0) );
FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
num_posted++;
}
@@ -1898,6 +1936,8 @@
if( bPost )
{
+ dprintf_winsock(stddeb, "\t hwnd %04x - %04x, %08x\n",
+ psop->hWnd, psop->uMsg, (unsigned)dwEvent );
PostMessage16( psop->hWnd, psop->uMsg,
(WPARAM16)WS_PTR2HANDLE(psop->pws), (LPARAM)dwEvent );
bPost = FALSE;
@@ -2053,7 +2093,8 @@
dprintf_winsock(stddeb, "WS_SetBlockingHook16(%08x): hook %08x\n",
(unsigned)pwsi, (unsigned) lpBlockFunc);
- if( pwsi ) {
+ if( pwsi )
+ {
prev = (FARPROC16)pwsi->blocking_hook;
pwsi->blocking_hook = (DWORD)lpBlockFunc;
pwsi->flags &= ~WSI_BLOCKINGHOOK32;