Skip to content

Fix sendmsg() implementation #24187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion src/lib/libsockfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ addToLibrary({
// connect, and lie, saying the data was sent now.
if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
// if we're not connected, open a new connection
if (sock.type === {{{ cDefs.SOCK_DGRAM }}}) {
if (!dest || sock.type === {{{ cDefs.SOCK_DGRAM }}}) {
if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
}
Expand Down
68 changes: 68 additions & 0 deletions test/sockets/test_sockets_sendmsg_to_invalid_dest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2025 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License. Both these licenses can be
// found in the LICENSE file.

#include <arpa/inet.h>
#include <emscripten.h>
#include <emscripten/eventloop.h>
#include <ifaddrs.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int sock;

bool wait_for_recv(double d, void* u) {
// Poll read from the socket to see what we have received
char buf[1024] = {};
recv(sock, buf, sizeof(buf) - 1, 0);
if (strlen(buf) > 0) {
printf("%s\n", buf);
if (!strcmp(buf, "Hello")) {
printf("Got hello, test finished.\n");
#ifdef REPORT_RESULT
REPORT_RESULT(0);
#endif
}
}
return EM_TRUE;
}

int main() {
// Connect socket to a WebSocket echo server
struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(8089)};
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
printf("socket() failed to error %d\n", sock);
return sock;
}

// Connect to echo server.
int error = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
if (error) {
printf("connect() failed to error %d\n", error);
return error;
}

// Immediately send a message back-to-back from connecting to the socket
const char* msg = "Hello";
ssize_t bytes = send(sock, msg, strlen(msg), 0);
if (bytes != strlen(msg)) {
printf("send() failed to send %d bytes. Return value: %d\n",
(int)strlen(msg),
(int)bytes);
return bytes;
}

// This shouldn't throw an exception in `sendmsg` implementation.
// [see GH-23046]
struct ifaddrs* ifaddrs = NULL;
getifaddrs(&ifaddrs);

// Asynchronously wait until we get the message echoed back
emscripten_set_timeout_loop(wait_for_recv, 0, 0);
return 0;
}
4 changes: 4 additions & 0 deletions test/test_sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ def test_sockets_send_while_connecting(self):
with NodeJsWebSocketEchoServerProcess():
self.btest('sockets/test_sockets_send_while_connecting.c', emcc_args=['-DSOCKET_DEBUG'], expected='0')

def test_sockets_sendmsg_to_invalid_dest(self):
with NodeJsWebSocketEchoServerProcess():
self.btest('sockets/test_sockets_sendmsg_to_invalid_dest.c', emcc_args=['-DSOCKET_DEBUG', '-lsockfs.js'], expected='0')


class sockets64(sockets):
def setUp(self):
Expand Down