Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix Windows build of ds-ipc-pal-socket.c and make FD_CLOEXEC best eff…
…ort.

Up until #55850 it was possible
to build using diagnostic server socket PAL on Windows for local testing.
NOTE, this is not a config we build on CI since it is not used by any
products (diagnostic server PAL on Windows uses NamedPipes), but useful
for local testing.

The same PR also included calls to fcntl using FD_CLOEXEC in case platform
doesn't define SOCK_CLOEXEC. Since this is a Linux specific flag, it might not
be defined on several targeted platforms. Failures calling fcntl using
FD_CLOEXEC was also triggering an EP_ASSERT but that is only on debug
builds. Most calls to fcntl using FD_CLOEXEC in runtime PAL layers
(both CoreCLR and MonoVM) doesn't check for errors in this case
and sees the operation as best effort, like done here
https://github.com/dotnet/runtime/blob/b937677e8f8601848d29bc072a93cc0c6e21576d/src/libraries/Native/Unix/System.Native/pal_networking.c#L2499.
We should do the same in ds-ipc-pal-socket.c making sure it won't break
any potential platform not fully supporting it or if we are really concerned
about this error, handle it as real error failing creation of socket, but
that needs to be tested on mobile platforms (not running TCP/IP PAL on CI).
  • Loading branch information
lateralusX committed Jul 22, 2021
commit 7470851707ef409a0bfdefdc4f78323a8a7a636c
13 changes: 5 additions & 8 deletions src/native/eventpipe/ds-ipc-pal-socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,8 @@ ipc_socket_create_uds (DiagnosticsIpc *ipc)
DS_ENTER_BLOCKING_PAL_SECTION;
new_socket = socket (ipc->server_address_family, socket_type, 0);
#ifndef SOCK_CLOEXEC
if (new_socket != DS_IPC_INVALID_SOCKET) {
if (fcntl (new_socket, F_SETFD, FD_CLOEXEC) == -1) {
EP_ASSERT (!"Failed to set CLOEXEC");
}
}
if (new_socket != DS_IPC_INVALID_SOCKET)
fcntl (new_socket, F_SETFD, FD_CLOEXEC); // ignore any failures; this is best effort
#endif // SOCK_CLOEXEC
DS_EXIT_BLOCKING_PAL_SECTION;
return new_socket;
Expand Down Expand Up @@ -356,9 +353,9 @@ ipc_socket_create_tcp (DiagnosticsIpc *ipc)
new_socket = socket (ipc->server_address_family, socket_type, IPPROTO_TCP);
if (new_socket != DS_IPC_INVALID_SOCKET) {
#ifndef SOCK_CLOEXEC
if (fcntl (new_socket, F_SETFD, FD_CLOEXEC) == -1) {
EP_ASSERT (!"Failed to set CLOEXEC");
}
#ifndef HOST_WIN32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should still check the existence of SOCK_CLOEXEC so we only do the fcntl call if we didn't already set it during the call to socket.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is already under #ifndef SOCK_CLOEXEC, or maybe you though about adding check for FD_CLOEXEC as well? That is not something we have done in other places doing similar code (just checking SOCK_CLOEXEC), and I know that some Mono headers actually define this on platforms where its not used/available, so on those platforms the additional check won't make any difference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, no I missed line 355 because I was reviewing this on my phone 🙄. If we're checking ifndef SOCK_CLOEXEC this is fine.

nit: #if !defined(SOCK_CLOEXEC) && !defined(HOST_WIN32)?

fcntl (new_socket, F_SETFD, FD_CLOEXEC); // ignore any failures; this is best effort
#endif // HOST_WIN32
#endif // SOCK_CLOEXEC
int option_value = 1;
setsockopt (new_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&option_value, sizeof (option_value));
Expand Down