emscripten-core / emscripten-core/emscripten

How to do error handling on `connect` ?

Open
#17,385 0 comments 3 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

**Version of emscripten/emsdk:**
```
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.13 (531257621816c200bc7c3be53129494afd029aec)
clang version 15.0.0 (https://github.com/llvm/llvm-project 5c6ed60c517c47b25b6b25d8ac3666d0e746b0c3)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/yanis/tools/emsdk/upstream/bin
```
____

Our application relies on the [Emulated POSIX TCP Sockets over WebSockets](https://emscripten.org/docs/porting/networking.html#emulated-posix-tcp-sockets-over-websockets) to connect to our server.
This is how we use `connect` then `select` to wait for the connection to be established before proceeding. This `select` step is needed because sockets are non blocking (O_NONBLOCK) when using emscripten:
```c
int status = connect(channel.socket_fd, (struct sockaddr *)&socket_inetaddr, sizeof(struct sockaddr_in));

#ifdef __EMSCRIPTEN__
if (errno == EINPROGRESS)
{
int is_write_ready = 0;
while (!is_write_ready)
{
emscripten_sleep(100); // 100ms

fd_set set;
FD_ZERO(&set);
FD_SET(channel.socket_fd, &set);

// TODO: Error handling if socket connect fails
is_write_ready = select(channel.socket_fd + 1, NULL, &set, NULL, NULL);
}

status = OK;
}
#endif
```
It is extremely similar to how `connect` and `select` are used together in the emscripten test suite
https://github.com/emscripten-core/emscripten/blob/9585abddd3c8dc7e1dcd0d19c469e992dc20d30c/tests/sockets/test_sockets_partial_client.c#L43-L52
And this works beautifully when it works, but when an error occurs (such as the server not being reachable), this code hangs indefinitely desperately waiting for the socket to become readable.
The `select` implementation provided by emscripten does not support the 3rd argument `errorfds` that would typically be used to check of fd for which an error occurred.
Question is: **How can we detect that `connect` failed ?**

The only solution I see would be to have a timeout after which we consider that the `connect` have failed, but that feels a bit dirty because we're not actually catching the error or anything

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.