Skip to content

Commit 202c4c9

Browse files
committed
Fix sendmsg() implementation
1 parent 5cdadd6 commit 202c4c9

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

src/lib/libsockfs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ addToLibrary({
632632
// connect, and lie, saying the data was sent now.
633633
if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
634634
// if we're not connected, open a new connection
635-
if (sock.type === {{{ cDefs.SOCK_DGRAM }}}) {
635+
if (!dest || sock.type === {{{ cDefs.SOCK_DGRAM }}}) {
636636
if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
637637
dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
638638
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2025 The Emscripten Authors. All rights reserved.
2+
// Emscripten is available under two separate licenses, the MIT license and the
3+
// University of Illinois/NCSA Open Source License. Both these licenses can be
4+
// found in the LICENSE file.
5+
6+
#include <arpa/inet.h>
7+
#include <emscripten.h>
8+
#include <emscripten/eventloop.h>
9+
#include <ifaddrs.h>
10+
#include <stdbool.h>
11+
#include <stdio.h>
12+
#include <string.h>
13+
#include <unistd.h>
14+
15+
int sock;
16+
17+
bool wait_for_recv(double d, void* u) {
18+
// Poll read from the socket to see what we have received
19+
char buf[1024] = {};
20+
recv(sock, buf, sizeof(buf) - 1, 0);
21+
if (strlen(buf) > 0) {
22+
printf("%s\n", buf);
23+
if (!strcmp(buf, "Hello")) {
24+
printf("Got hello, test finished.\n");
25+
#ifdef REPORT_RESULT
26+
REPORT_RESULT(0);
27+
#endif
28+
}
29+
}
30+
return EM_TRUE;
31+
}
32+
33+
int main() {
34+
// Connect socket to a WebSocket echo server
35+
struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(8089)};
36+
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
37+
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
38+
if (sock < 0) {
39+
printf("socket() failed to error %d\n", sock);
40+
return sock;
41+
}
42+
43+
// Connect to echo server.
44+
int error = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
45+
if (error) {
46+
printf("connect() failed to error %d\n", error);
47+
return error;
48+
}
49+
50+
// Immediately send a message back-to-back from connecting to the socket
51+
const char* msg = "Hello";
52+
ssize_t bytes = send(sock, msg, strlen(msg), 0);
53+
if (bytes != strlen(msg)) {
54+
printf("send() failed to send %d bytes. Return value: %d\n",
55+
(int)strlen(msg),
56+
(int)bytes);
57+
return bytes;
58+
}
59+
60+
// This shouldn't throw an exception in `sendmsg` implementation.
61+
// [see GH-23046]
62+
struct ifaddrs* ifaddrs = NULL;
63+
getifaddrs(&ifaddrs);
64+
65+
// Asynchronously wait until we get the message echoed back
66+
emscripten_set_timeout_loop(wait_for_recv, 0, 0);
67+
return 0;
68+
}

test/test_sockets.py

+4
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ def test_sockets_send_while_connecting(self):
359359
with NodeJsWebSocketEchoServerProcess():
360360
self.btest('sockets/test_sockets_send_while_connecting.c', emcc_args=['-DSOCKET_DEBUG'], expected='0')
361361

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

363367
class sockets64(sockets):
364368
def setUp(self):

0 commit comments

Comments
 (0)