Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f4df896e
Commit
f4df896e
authored
Jun 29, 2021
by
Zebediah Figura
Committed by
Alexandre Julliard
Jun 29, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ws2_32: Handle SO_RCVTIMEO in the server.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
8aaf9e64
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
44 additions
and
16 deletions
+44
-16
socket.c
dlls/ws2_32/socket.c
+5
-5
sock.c
dlls/ws2_32/tests/sock.c
+4
-4
afd.h
include/wine/afd.h
+2
-0
sock.c
server/sock.c
+33
-7
No files found.
dlls/ws2_32/socket.c
View file @
f4df896e
...
...
@@ -2289,6 +2289,8 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
return
server_getsockopt
(
s
,
IOCTL_AFD_WINE_GET_SO_RCVBUF
,
optval
,
optlen
);
case
WS_SO_RCVTIMEO
:
return
server_getsockopt
(
s
,
IOCTL_AFD_WINE_GET_SO_RCVTIMEO
,
optval
,
optlen
);
case
WS_SO_SNDTIMEO
:
{
INT64
timeout
;
...
...
@@ -3565,6 +3567,9 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
case
WS_SO_RCVBUF
:
return
server_setsockopt
(
s
,
IOCTL_AFD_WINE_SET_SO_RCVBUF
,
optval
,
optlen
);
case
WS_SO_RCVTIMEO
:
return
server_setsockopt
(
s
,
IOCTL_AFD_WINE_SET_SO_RCVTIMEO
,
optval
,
optlen
);
/* Some options need some conversion before they can be sent to
* setsockopt. The conversions are done here, then they will fall through
* to the general case. Special options that are not passed to
...
...
@@ -3631,13 +3636,8 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
TRACE
(
"setting global SO_OPENTYPE = 0x%x
\n
"
,
*
((
const
int
*
)
optval
)
);
return
0
;
#ifdef SO_RCVTIMEO
case
WS_SO_RCVTIMEO
:
#endif
#ifdef SO_SNDTIMEO
case
WS_SO_SNDTIMEO
:
#endif
#if defined(SO_RCVTIMEO) || defined(SO_SNDTIMEO)
if
(
optval
&&
optlen
==
sizeof
(
UINT32
))
{
/* WinSock passes milliseconds instead of struct timeval */
tval
.
tv_usec
=
(
*
(
const
UINT32
*
)
optval
%
1000
)
*
1000
;
...
...
dlls/ws2_32/tests/sock.c
View file @
f4df896e
...
...
@@ -10919,7 +10919,7 @@ static void test_timeout(void)
WSASetLastError
(
0xdeadbeef
);
ret
=
getsockopt
(
client
,
SOL_SOCKET
,
SO_RCVTIMEO
,
(
char
*
)
&
timeout
,
&
len
);
ok
(
!
ret
,
"expected success
\n
"
);
todo_wine
ok
(
!
WSAGetLastError
(),
"got error %u
\n
"
,
WSAGetLastError
());
ok
(
!
WSAGetLastError
(),
"got error %u
\n
"
,
WSAGetLastError
());
ok
(
len
==
sizeof
(
timeout
),
"got size %u
\n
"
,
len
);
ok
(
!
timeout
,
"got timeout %u
\n
"
,
timeout
);
...
...
@@ -10927,15 +10927,15 @@ static void test_timeout(void)
WSASetLastError
(
0xdeadbeef
);
ret
=
setsockopt
(
client
,
SOL_SOCKET
,
SO_RCVTIMEO
,
(
char
*
)
&
timeout
,
sizeof
(
timeout
));
ok
(
!
ret
,
"expected success
\n
"
);
todo_wine
ok
(
!
WSAGetLastError
(),
"got error %u
\n
"
,
WSAGetLastError
());
ok
(
!
WSAGetLastError
(),
"got error %u
\n
"
,
WSAGetLastError
());
timeout
=
0xdeadbeef
;
len
=
sizeof
(
timeout
);
WSASetLastError
(
0xdeadbeef
);
ret
=
getsockopt
(
client
,
SOL_SOCKET
,
SO_RCVTIMEO
,
(
char
*
)
&
timeout
,
&
len
);
ok
(
!
ret
,
"expected success
\n
"
);
todo_wine
ok
(
!
WSAGetLastError
(),
"got error %u
\n
"
,
WSAGetLastError
());
todo_wine
ok
(
timeout
==
100
,
"got timeout %u
\n
"
,
timeout
);
ok
(
!
WSAGetLastError
(),
"got error %u
\n
"
,
WSAGetLastError
());
ok
(
timeout
==
100
,
"got timeout %u
\n
"
,
timeout
);
WSASetLastError
(
0xdeadbeef
);
ret
=
recv
(
client
,
&
buffer
,
1
,
0
);
...
...
include/wine/afd.h
View file @
f4df896e
...
...
@@ -171,6 +171,8 @@ struct afd_get_events_params
#define IOCTL_AFD_WINE_SET_SO_OOBINLINE CTL_CODE(FILE_DEVICE_NETWORK, 228, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_WINE_SET_SO_RCVBUF CTL_CODE(FILE_DEVICE_NETWORK, 229, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_WINE_GET_SO_RCVBUF CTL_CODE(FILE_DEVICE_NETWORK, 230, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_WINE_SET_SO_RCVTIMEO CTL_CODE(FILE_DEVICE_NETWORK, 231, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_WINE_GET_SO_RCVTIMEO CTL_CODE(FILE_DEVICE_NETWORK, 232, METHOD_BUFFERED, FILE_ANY_ACCESS)
struct
afd_create_params
{
...
...
server/sock.c
View file @
f4df896e
...
...
@@ -208,6 +208,7 @@ struct sock
union
win_sockaddr
addr
;
/* socket name */
int
addr_len
;
/* socket name length */
unsigned
int
rcvbuf
;
/* advisory recv buffer size */
unsigned
int
rcvtimeo
;
/* receive timeout in ms */
unsigned
int
rd_shutdown
:
1
;
/* is the read end shut down? */
unsigned
int
wr_shutdown
:
1
;
/* is the write end shut down? */
unsigned
int
wr_shutdown_pending
:
1
;
/* is a write shutdown pending? */
...
...
@@ -1388,6 +1389,7 @@ static struct sock *create_socket(void)
sock
->
nonblocking
=
0
;
sock
->
bound
=
0
;
sock
->
rcvbuf
=
0
;
sock
->
rcvtimeo
=
0
;
init_async_queue
(
&
sock
->
read_q
);
init_async_queue
(
&
sock
->
write_q
);
init_async_queue
(
&
sock
->
ifchange_q
);
...
...
@@ -2619,6 +2621,35 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
return
0
;
}
case
IOCTL_AFD_WINE_GET_SO_RCVTIMEO
:
{
DWORD
rcvtimeo
=
sock
->
rcvtimeo
;
if
(
get_reply_max_size
()
<
sizeof
(
rcvtimeo
))
{
set_error
(
STATUS_BUFFER_TOO_SMALL
);
return
0
;
}
set_reply_data
(
&
rcvtimeo
,
sizeof
(
rcvtimeo
)
);
return
1
;
}
case
IOCTL_AFD_WINE_SET_SO_RCVTIMEO
:
{
DWORD
rcvtimeo
;
if
(
get_req_data_size
()
<
sizeof
(
rcvtimeo
))
{
set_error
(
STATUS_BUFFER_TOO_SMALL
);
return
0
;
}
rcvtimeo
=
*
(
DWORD
*
)
get_req_data
();
sock
->
rcvtimeo
=
rcvtimeo
;
return
0
;
}
default:
set_error
(
STATUS_NOT_SUPPORTED
);
return
0
;
...
...
@@ -3029,19 +3060,14 @@ DECL_HANDLER(recv_socket)
/* recv() returned EWOULDBLOCK, i.e. no data available yet */
if
(
status
==
STATUS_DEVICE_NOT_READY
&&
!
sock
->
nonblocking
)
{
#ifdef SO_RCVTIMEO
struct
timeval
tv
;
socklen_t
len
=
sizeof
(
tv
);
/* Set a timeout on the async if necessary.
*
* We want to do this *only* if the client gave us STATUS_DEVICE_NOT_READY.
* If the client gave us STATUS_PENDING, it expects the async to always
* block (it was triggered by WSARecv*() with a valid OVERLAPPED
* structure) and for the timeout not to be respected. */
if
(
is_fd_overlapped
(
fd
)
&&
!
getsockopt
(
get_unix_fd
(
fd
),
SOL_SOCKET
,
SO_RCVTIMEO
,
(
char
*
)
&
tv
,
&
len
))
timeout
=
tv
.
tv_sec
*
-
10000000
+
tv
.
tv_usec
*
-
10
;
#endif
if
(
is_fd_overlapped
(
fd
))
timeout
=
(
timeout_t
)
sock
->
rcvtimeo
*
-
10000
;
status
=
STATUS_PENDING
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment