ws2_32: Lock the user output buffer during receives.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c583953b95
commit
dc203dd833
|
@ -1480,6 +1480,9 @@
|
|||
@ cdecl wine_server_send_fd(long)
|
||||
@ cdecl __wine_make_process_system()
|
||||
|
||||
# Virtual memory
|
||||
@ cdecl __wine_locked_recvmsg(long ptr long)
|
||||
|
||||
# Version
|
||||
@ cdecl wine_get_version() NTDLL_wine_get_version
|
||||
@ cdecl wine_get_build_id() NTDLL_wine_get_build_id
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
@ -1904,6 +1907,36 @@ ssize_t virtual_locked_pread( int fd, void *addr, size_t size, off_t offset )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* __wine_locked_recvmsg
|
||||
*/
|
||||
ssize_t CDECL __wine_locked_recvmsg( int fd, struct msghdr *hdr, int flags )
|
||||
{
|
||||
sigset_t sigset;
|
||||
size_t i;
|
||||
BOOL has_write_watch = FALSE;
|
||||
int err = EFAULT;
|
||||
|
||||
ssize_t ret = recvmsg( fd, hdr, flags );
|
||||
if (ret != -1 || errno != EFAULT) return ret;
|
||||
|
||||
server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||
for (i = 0; i < hdr->msg_iovlen; i++)
|
||||
if (check_write_access( hdr->msg_iov[i].iov_base, hdr->msg_iov[i].iov_len, &has_write_watch ))
|
||||
break;
|
||||
if (i == hdr->msg_iovlen)
|
||||
{
|
||||
ret = recvmsg( fd, hdr, flags );
|
||||
err = errno;
|
||||
}
|
||||
if (has_write_watch)
|
||||
while (i--) update_write_watches( hdr->msg_iov[i].iov_base, hdr->msg_iov[i].iov_len, 0 );
|
||||
|
||||
server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||
errno = err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* virtual_is_valid_code_address
|
||||
|
|
|
@ -241,6 +241,8 @@ static struct interface_filter generic_interface_filter = {
|
|||
};
|
||||
#endif /* LINUX_BOUND_IF */
|
||||
|
||||
extern ssize_t CDECL __wine_locked_recvmsg( int fd, struct msghdr *hdr, int flags );
|
||||
|
||||
/*
|
||||
* The actual definition of WSASendTo, wrapped in a different function name
|
||||
* so that internal calls from ws2_32 itself will not trigger programs like
|
||||
|
@ -2356,7 +2358,7 @@ static int WS2_recv( int fd, struct ws2_async *wsa, int flags )
|
|||
hdr.msg_flags = 0;
|
||||
#endif
|
||||
|
||||
while ((n = recvmsg(fd, &hdr, flags)) == -1)
|
||||
while ((n = __wine_locked_recvmsg( fd, &hdr, flags )) == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
return -1;
|
||||
|
|
|
@ -6962,13 +6962,10 @@ static void test_write_watch(void)
|
|||
send(src, "test message", sizeof("test message"), 0);
|
||||
|
||||
ret = GetOverlappedResult( (HANDLE)dest, &ov, &bytesReturned, TRUE );
|
||||
todo_wine
|
||||
{
|
||||
ok( ret, "GetOverlappedResult failed %u\n", GetLastError() );
|
||||
ok( bytesReturned == sizeof("test message"), "wrong size %u\n", bytesReturned );
|
||||
ok( !memcmp( base, "test ", 5 ), "wrong data %s\n", base );
|
||||
ok( !memcmp( base + 0x4000, "message", 8 ), "wrong data %s\n", base + 0x4000 );
|
||||
}
|
||||
|
||||
count = 64;
|
||||
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
|
||||
|
@ -6984,7 +6981,6 @@ static void test_write_watch(void)
|
|||
bufs[1].len = 0x4000;
|
||||
bufs[1].buf = base + 0x2000;
|
||||
ret = WSARecvFrom( dest, bufs, 2, NULL, &flags, &addr, &addr_len, &ov, NULL);
|
||||
todo_wine
|
||||
ok(ret == SOCKET_ERROR && GetLastError() == ERROR_IO_PENDING,
|
||||
"WSARecv failed - %d error %d\n", ret, GetLastError());
|
||||
|
||||
|
@ -6992,7 +6988,6 @@ static void test_write_watch(void)
|
|||
ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
|
||||
ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
|
||||
ok( count == 5, "wrong count %lu\n", count );
|
||||
todo_wine
|
||||
ok( !base[0], "data set\n" );
|
||||
|
||||
send(src, "test message", sizeof("test message"), 0);
|
||||
|
|
Loading…
Reference in New Issue