Skip to content

Commit 7cf5386

Browse files
committed
Fix sendmsg() implementation
1 parent dde19fa commit 7cf5386

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

src/library_sockfs.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,8 @@ addToLibrary({
634634
// connect, and lie, saying the data was sent now.
635635
if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
636636
// if we're not connected, open a new connection
637-
if (sock.type === {{{ cDefs.SOCK_DGRAM }}}) {
637+
if (!dest || sock.type === {{{ cDefs.SOCK_DGRAM }}}) {
638+
sock.type = {{{ cDefs.SOCK_DGRAM }}};
638639
if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
639640
dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
640641
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2013 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 <stdio.h>
11+
#include <string.h>
12+
#include <unistd.h>
13+
14+
int sock;
15+
16+
EM_BOOL wait_for_recv(double d, void* u) {
17+
// Poll read from the socket to see what we have received
18+
char buf[1024] = {};
19+
recv(sock, buf, sizeof(buf) - 1, 0);
20+
if (strlen(buf) > 0) {
21+
printf("%s\n", buf);
22+
if (!strcmp(buf, "Hello")) {
23+
printf("Got hello, test finished.\n");
24+
#ifdef REPORT_RESULT
25+
REPORT_RESULT(0);
26+
#endif
27+
}
28+
}
29+
return EM_TRUE;
30+
}
31+
32+
int main() {
33+
// Connect socket to a WebSocket echo server
34+
struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(8089)};
35+
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
36+
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
37+
if (sock < 0) {
38+
printf("socket() failed to error %d\n", sock);
39+
return sock;
40+
}
41+
42+
// Connect to echo server.
43+
int error = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
44+
if (error) {
45+
printf("connect() failed to error %d\n", error);
46+
return error;
47+
}
48+
49+
// Immediately send a message back-to-back from connecting to the socket
50+
const char* msg = "Hello";
51+
ssize_t bytes = send(sock, msg, strlen(msg), 0);
52+
if (bytes != strlen(msg)) {
53+
printf("send() failed to send %d bytes. Return value: %d\n",
54+
(int)strlen(msg),
55+
(int)bytes);
56+
return bytes;
57+
}
58+
59+
// This shouldn't throw an exception in `sendmsg` implementation.
60+
// [see GH-23046]
61+
struct ifaddrs* ifaddrs = NULL;
62+
getifaddrs(&ifaddrs);
63+
64+
// Asynchronously wait until we get the message echoed back
65+
emscripten_set_timeout_loop(wait_for_recv, 0, 0);
66+
return 0;
67+
}

test/test_sockets.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ def test_sockets_send_while_connecting(self):
363363
with NodeJsWebSocketEchoServerProcess():
364364
self.btest('sockets/test_sockets_send_while_connecting.c', args=['-DSOCKET_DEBUG'], expected='0')
365365

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

367371
class sockets64(sockets):
368372
def setUp(self):

0 commit comments

Comments
 (0)