Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
173 commits
Select commit Hold shift + click to select a range
be1fdbe
test-child-process-reject-null-bytes
pfgithub Mar 31, 2025
f1dc926
test-child-process-emfile
pfgithub Apr 1, 2025
d828f25
match node logic more closely
pfgithub Apr 1, 2025
887ee53
support both emfile and enfile
pfgithub Apr 1, 2025
2d0829b
test-child-process-spawnsync-kill-signal
pfgithub Apr 1, 2025
57376f2
test-child-process-spawnsync-shell.js
pfgithub Apr 1, 2025
58dbcb0
test-child-process-windows-hide
pfgithub Apr 1, 2025
4da8ce1
test-child-process-detached
pfgithub Apr 1, 2025
511182f
test-child-process-prototype-tampering
pfgithub Apr 2, 2025
70cb404
abort signal stuff?
pfgithub Apr 3, 2025
1fc70f4
use recvmsg() on ipc sockets
pfgithub Apr 3, 2025
1932f61
on_fd
pfgithub Apr 4, 2025
185d417
unify doSend & fix the error is supposed to be on nextTick
pfgithub Apr 4, 2025
85045a6
write fd fn
pfgithub Apr 5, 2025
a1356ec
Merge branch 'main' into pfg/child-process
pfgithub Apr 5, 2025
0a03f64
unify serializeAndSend{,Internal}
pfgithub Apr 5, 2025
8ec6bca
WIPPIW
pfgithub Apr 7, 2025
f64058a
PIWIPIWIP
pfgithub Apr 7, 2025
1adf00f
no anytype
pfgithub Apr 7, 2025
25cad68
WIPPWI
pfgithub Apr 8, 2025
b23c79c
add ipc deinit and use it
pfgithub Apr 8, 2025
5152f3a
maybe prepared for sending an ack now?
pfgithub Apr 8, 2025
922ede7
fix musl build
pfgithub Apr 9, 2025
7ea23d0
note
pfgithub Apr 9, 2025
9b49af4
handle empty to_send case
pfgithub Apr 9, 2025
7769fda
WIPWPIWIPW
pfgithub Apr 9, 2025
d747f41
WIWIPPIWWWIPWWIPPI
pfgithub Apr 9, 2025
b1fa295
<wip|piw|wip|piw>
pfgithub Apr 10, 2025
0f2806f
merge internal/deternal codepaths
pfgithub Apr 10, 2025
e4035db
remove the (hopefully) unreachable panic
pfgithub Apr 10, 2025
dc3d16c
revert net change
pfgithub Apr 10, 2025
4c06efc
use fastGet over get
pfgithub Apr 10, 2025
7a3bbb4
(cont.d)
pfgithub Apr 10, 2025
de77f13
begin ipc.ts
pfgithub Apr 10, 2025
09e9082
wip
pfgithub Apr 10, 2025
2c34f0c
fixes 1
pfgithub Apr 10, 2025
4c10033
fixes 2
pfgithub Apr 10, 2025
1b6cb70
get test-child-process-fork passing again
pfgithub Apr 10, 2025
8823893
pass node-http2.ts again
pfgithub Apr 10, 2025
d3d57a9
pass serve.test.ts again
pfgithub Apr 10, 2025
d86f8ec
improve bundle-functions error display
pfgithub Apr 10, 2025
22f6f2e
call js from zig now?
pfgithub Apr 10, 2025
4a29147
remove std log info
pfgithub Apr 10, 2025
87d6cfe
ban std.log.info
pfgithub Apr 10, 2025
8f3e837
(ban-words) std.debug.print -> limit 0
pfgithub Apr 11, 2025
04b3127
(ban-words) std.mem.indexOfAny(u8 -> limit 0
pfgithub Apr 11, 2025
1ca57ae
notes
pfgithub Apr 11, 2025
997143e
Merge branch 'main' into pfg/child-process
pfgithub Apr 11, 2025
0f047ee
fix after merge
pfgithub Apr 11, 2025
51f3496
pass test-child-process-send-after-close again
pfgithub Apr 11, 2025
4c486a1
simplify? logic
pfgithub Apr 11, 2025
9397a41
fix where makeAbortError is called so it doesn't call it at the wrong…
pfgithub Apr 11, 2025
1b74733
fix child_process_ipc.test.js
pfgithub Apr 11, 2025
fb3fabb
wip
pfgithub Apr 11, 2025
bfd648e
use single quote rather than double quote
pfgithub Apr 11, 2025
7219238
WIPWIPWIP
pfgithub Apr 11, 2025
c3c601d
remove unneeded headers
pfgithub Apr 11, 2025
2bdaccb
fix creating the ipc socket for the child
pfgithub Apr 11, 2025
27a1d0d
it sends a server. doesn't work yet though
pfgithub Apr 12, 2025
0df9b24
send the right message
pfgithub Apr 12, 2025
bbb67f1
notes
pfgithub Apr 12, 2025
285e701
eintr
pfgithub Apr 12, 2025
a648eaf
it was listening with port = fd rather than trying to listen on the fd.
pfgithub Apr 12, 2025
ccd9314
child listens on fd maybe?
pfgithub Apr 14, 2025
549e720
Merge branch 'main' into pfg/child-process
pfgithub Apr 14, 2025
4a02c57
double-connect repro
pfgithub Apr 15, 2025
4957d13
notes
pfgithub Apr 15, 2025
2fa6fe5
add the remaining send fd related tests
pfgithub Apr 15, 2025
accd9ab
fix a queue problem & return backoff indication
pfgithub Apr 15, 2025
6f9cb67
need to always add a handle to the queue because each may have its ow…
pfgithub Apr 15, 2025
3d983de
`bun run prettier:extra`
pfgithub Apr 15, 2025
aa08852
protect the callback!
pfgithub Apr 15, 2025
77e0ac6
remove unused comment
pfgithub Apr 15, 2025
2321d15
wip serialize net.Socket
pfgithub Apr 15, 2025
d29a9d6
ipc.ts fix
pfgithub Apr 16, 2025
c38f9d6
move more into SendQueue to be shared across platform
pfgithub Apr 16, 2025
e96c6e9
move internal_msg_queue, incoming, incoming_fd to SendQueue
pfgithub Apr 16, 2025
62f8eff
wip windows
pfgithub Apr 16, 2025
c1f7ff5
it builds on windows
pfgithub Apr 16, 2025
4e4f699
Merge branch 'main' into pfg/child-process
pfgithub Apr 16, 2025
66b8313
fix build after merge
pfgithub Apr 16, 2025
3646deb
remove unneeded throw
pfgithub Apr 17, 2025
0428371
fix missing break in switch
pfgithub Apr 17, 2025
ffba9e9
Merge branch 'main' into pfg/child-process
pfgithub Apr 17, 2025
f1eb409
Merge branch 'main' into pfg/child-process
pfgithub Apr 17, 2025
51fde5f
disable sending handles for now
pfgithub Apr 17, 2025
a87a4fb
remove send handle related tests
pfgithub Apr 17, 2025
c223b21
maybe windows
pfgithub Apr 17, 2025
8cfbcef
un-modify launch.json
pfgithub Apr 18, 2025
fef56c7
getAckPacket/getNackPacket for advanced serialization
pfgithub Apr 18, 2025
66e8cd2
eliminate panics
pfgithub Apr 18, 2025
47c344a
disable double-connect
pfgithub Apr 18, 2025
21450ea
fix build on windows
pfgithub Apr 18, 2025
1d3834f
fix windows duplicate of has_written_version
pfgithub Apr 18, 2025
2a955d6
debug logging
pfgithub Apr 18, 2025
1d59912
windows was missing .flush()
pfgithub Apr 18, 2025
b62fa59
windows systemerrno uv errors?
pfgithub Apr 18, 2025
34a6a39
fix the log
pfgithub Apr 19, 2025
28d7c80
move the windows_c
pfgithub Apr 19, 2025
6de6e6b
forgot the helpers.cpp change
pfgithub Apr 19, 2025
90a34c4
complete array
pfgithub Apr 19, 2025
d666ed4
enhanced send cb test
pfgithub Apr 19, 2025
794fee5
add uv.h include
pfgithub Apr 19, 2025
184b391
Merge branch 'main' into pfg/child-process
pfgithub Apr 21, 2025
499124a
fix match
pfgithub Apr 21, 2025
c0df4eb
fix [0m in the test
pfgithub Apr 21, 2025
38f8834
test-child-process-stdin
pfgithub Apr 21, 2025
b142ef6
set NO_COLOR for child_process_send_cb_test
pfgithub Apr 21, 2025
f716d57
pass lint
pfgithub Apr 21, 2025
b25c419
Merge branch 'main' into pfg/child-process
pfgithub Apr 22, 2025
d5e4e40
allow fd parameter in listen for listen-fd-ebadf, but not implemented…
pfgithub Apr 23, 2025
3cb622c
Merge branch 'main' into pfg/child-process
pfgithub Apr 24, 2025
bcd22fd
fix build after merge
pfgithub Apr 24, 2025
a05cccf
update ban-words after merge
pfgithub Apr 25, 2025
5491f26
Merge branch 'main' into pfg/child-process
pfgithub Apr 25, 2025
9e1bb89
update ban-words
pfgithub Apr 25, 2025
b5ee576
disconnectIPC on subprocess finalize
pfgithub Apr 26, 2025
e761e8b
WIP
pfgithub Apr 28, 2025
48d969d
Merge branch 'main' into pfg/child-process
pfgithub Apr 28, 2025
a45a7b1
posix keep ipc instance alive
pfgithub Apr 28, 2025
8b8520d
use debug allocator for ipc
pfgithub Apr 28, 2025
87dc7b7
add watch-windows script
pfgithub Apr 28, 2025
6968842
.
pfgithub Apr 28, 2025
dc759ac
close next tick -> sendqueue
pfgithub Apr 28, 2025
a96e6e4
eliminate the SocketType
pfgithub Apr 28, 2025
e7110af
ipc: move out of a generic fn
pfgithub Apr 29, 2025
30619fa
WIP WIP WIP WIP windows
pfgithub Apr 29, 2025
12245af
it builds on windows
pfgithub Apr 29, 2025
f8707c9
add debug logging to ipc
pfgithub Apr 30, 2025
340a041
windows fix (libuv never returns partial writes. succesful writes ret…
pfgithub Apr 30, 2025
2adef9a
fixes
pfgithub Apr 30, 2025
f005ab3
fix process.connected & error in the not connected case
pfgithub Apr 30, 2025
7495a51
no way
pfgithub Apr 30, 2025
251f926
disconnect on both sides & disable keep-alive on close & windows tryW…
pfgithub May 1, 2025
fda0f13
make sure windows write won't uaf & remove the tryWrite
pfgithub May 1, 2025
bb84863
send on the next tick rather than immediately. this fixes test-cluste…
pfgithub May 1, 2025
23cb93c
revert nextTick
pfgithub May 1, 2025
24ceda2
missed one
pfgithub May 1, 2025
bf7e66c
Merge branch 'main' into pfg/child-process
pfgithub May 1, 2025
ac1bf86
don't unref before close
pfgithub May 1, 2025
573c08e
update child_process_ipc_large_disconnect
pfgithub May 1, 2025
2ea54fe
windows: close after writes complete
pfgithub May 1, 2025
9f931ce
windows
pfgithub May 2, 2025
acda568
one last windows fix?
pfgithub May 2, 2025
8abee66
two last windows fix
pfgithub May 2, 2025
400c39b
if a write fails, close immediately
pfgithub May 2, 2025
38bd0d2
posix fix
pfgithub May 2, 2025
25ea7ed
fix
pfgithub May 2, 2025
064110f
Merge branch 'main' into pfg/child-process
pfgithub May 2, 2025
b234a08
Merge branch 'main' into pfg/child-process
pfgithub May 2, 2025
5be1a32
formatting
pfgithub May 3, 2025
26c2169
remove us_socket_context_listen_fd for now
pfgithub May 3, 2025
b036a99
make globalThis not nullable
pfgithub May 3, 2025
fe9ee1d
use bin.String.empty for function name
pfgithub May 3, 2025
3c9a1dc
remove todo comment
pfgithub May 3, 2025
b1fe533
CallbackList structure
pfgithub May 5, 2025
a71e807
move is_ipc to flags
pfgithub May 5, 2025
ef0e5a3
fix windows build
pfgithub May 5, 2025
ab10d0d
windows fix 2
pfgithub May 6, 2025
d44d019
Merge branch 'main' into pfg/child-process
pfgithub May 6, 2025
5d7be00
check us_socket_is_closed in on_fd callback and do the `s = `
pfgithub May 6, 2025
cfbb19b
comment us_socket_ipc_write_fd
pfgithub May 6, 2025
019b500
update ban-words
pfgithub May 7, 2025
8a900c9
Merge branch 'main' into pfg/child-process
pfgithub May 7, 2025
e146535
revert change in bun_shim_impl
pfgithub May 7, 2025
58cb872
fix double-wrapped abort error
pfgithub May 7, 2025
aed8c65
more accurate fd handling
pfgithub May 7, 2025
eb7f175
listen fd changes
pfgithub May 7, 2025
b1ca4b0
fd error
pfgithub May 7, 2025
6e387f1
.
pfgithub May 7, 2025
299f4be
fix
pfgithub May 7, 2025
32dcfdc
fix lint
pfgithub May 7, 2025
b09dfe6
allow one std.log
pfgithub May 7, 2025
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"scripts": {
"build": "bun run build:debug",
"watch": "zig build check --watch -fincremental --prominent-compile-errors --global-cache-dir build/debug/zig-check-cache --zig-lib-dir vendor/zig/lib",
"watch-windows": "zig build check-windows --watch -fincremental --prominent-compile-errors --global-cache-dir build/debug/zig-check-cache --zig-lib-dir vendor/zig/lib",
"bd": "(bun run --silent build:debug &> /tmp/bun.debug.build.log || (cat /tmp/bun.debug.build.log && rm -rf /tmp/bun.debug.build.log && exit 1)) && rm -f /tmp/bun.debug.build.log && ./build/debug/bun-debug",
"build:debug": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Debug -B build/debug",
"build:valgrind": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Debug -DENABLE_BASELINE=ON -ENABLE_VALGRIND=ON -B build/debug-valgrind",
Expand Down
3 changes: 2 additions & 1 deletion packages/bun-types/bun.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6613,9 +6613,10 @@ declare module "bun" {
ipc?(
message: any,
/**
* The {@link Subprocess} that sent the message
* The {@link Subprocess} that received the message
*/
subprocess: Subprocess<In, Out, Err>,
handle?: unknown,
): void;

/**
Expand Down
28 changes: 28 additions & 0 deletions packages/bun-usockets/src/bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,20 @@ ssize_t bsd_recv(LIBUS_SOCKET_DESCRIPTOR fd, void *buf, int length, int flags) {
}
}

#if !defined(_WIN32)
ssize_t bsd_recvmsg(LIBUS_SOCKET_DESCRIPTOR fd, struct msghdr *msg, int flags) {
while (1) {
ssize_t ret = recvmsg(fd, msg, flags);

if (UNLIKELY(IS_EINTR(ret))) {
continue;
}

return ret;
}
}
#endif

#if !defined(_WIN32)
#include <sys/uio.h>

Expand Down Expand Up @@ -783,6 +797,20 @@ ssize_t bsd_send(LIBUS_SOCKET_DESCRIPTOR fd, const char *buf, int length, int ms
}
}

#if !defined(_WIN32)
ssize_t bsd_sendmsg(LIBUS_SOCKET_DESCRIPTOR fd, const struct msghdr *msg, int flags) {
while (1) {
ssize_t rc = sendmsg(fd, msg, flags);

if (UNLIKELY(IS_EINTR(rc))) {
continue;
}

return rc;
}
}
#endif

int bsd_would_block() {
#ifdef _WIN32
return WSAGetLastError() == WSAEWOULDBLOCK;
Expand Down
28 changes: 20 additions & 8 deletions packages/bun-usockets/src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,14 +279,15 @@ struct us_socket_context_t *us_create_socket_context(int ssl, struct us_loop_t *
return context;
}

struct us_socket_context_t *us_create_bun_socket_context(int ssl, struct us_loop_t *loop, int context_ext_size, struct us_bun_socket_context_options_t options, enum create_bun_socket_error_t *err) {
struct us_socket_context_t *us_create_bun_ssl_socket_context(struct us_loop_t *loop, int context_ext_size, struct us_bun_socket_context_options_t options, enum create_bun_socket_error_t *err) {
#ifndef LIBUS_NO_SSL
if (ssl) {
/* This function will call us, again, with SSL = false and a bigger ext_size */
return (struct us_socket_context_t *) us_internal_bun_create_ssl_socket_context(loop, context_ext_size, options, err);
}
/* This function will call us, again, with SSL = false and a bigger ext_size */
return (struct us_socket_context_t *) us_internal_bun_create_ssl_socket_context(loop, context_ext_size, options, err);
#endif
return us_create_bun_nossl_socket_context(loop, context_ext_size);
}

struct us_socket_context_t *us_create_bun_nossl_socket_context(struct us_loop_t *loop, int context_ext_size) {
/* This path is taken once either way - always BEFORE whatever SSL may do LATER.
* context_ext_size will however be modified larger in case of SSL, to hold SSL extensions */

Expand Down Expand Up @@ -370,8 +371,8 @@ struct us_listen_socket_t *us_socket_context_listen(int ssl, struct us_socket_co
ls->s.timeout = 255;
ls->s.long_timeout = 255;
ls->s.flags.low_prio_state = 0;
ls->s.flags.is_paused = 0;

ls->s.flags.is_paused = 0;
ls->s.flags.is_ipc = 0;
ls->s.next = 0;
ls->s.flags.allow_half_open = (options & LIBUS_SOCKET_ALLOW_HALF_OPEN);
us_internal_socket_context_link_listen_socket(context, ls);
Expand Down Expand Up @@ -406,6 +407,7 @@ struct us_listen_socket_t *us_socket_context_listen_unix(int ssl, struct us_sock
ls->s.flags.low_prio_state = 0;
ls->s.flags.allow_half_open = (options & LIBUS_SOCKET_ALLOW_HALF_OPEN);
ls->s.flags.is_paused = 0;
ls->s.flags.is_ipc = 0;
ls->s.next = 0;
us_internal_socket_context_link_listen_socket(context, ls);

Expand All @@ -414,7 +416,6 @@ struct us_listen_socket_t *us_socket_context_listen_unix(int ssl, struct us_sock
return ls;
}


struct us_socket_t* us_socket_context_connect_resolved_dns(struct us_socket_context_t *context, struct sockaddr_storage* addr, int options, int socket_ext_size) {
LIBUS_SOCKET_DESCRIPTOR connect_socket_fd = bsd_create_connect_socket(addr, options);
if (connect_socket_fd == LIBUS_SOCKET_ERROR) {
Expand All @@ -437,6 +438,7 @@ struct us_socket_t* us_socket_context_connect_resolved_dns(struct us_socket_cont
socket->flags.low_prio_state = 0;
socket->flags.allow_half_open = (options & LIBUS_SOCKET_ALLOW_HALF_OPEN);
socket->flags.is_paused = 0;
socket->flags.is_ipc = 0;
socket->connect_state = NULL;


Expand Down Expand Up @@ -563,6 +565,7 @@ int start_connections(struct us_connecting_socket_t *c, int count) {
s->flags.low_prio_state = 0;
s->flags.allow_half_open = (c->options & LIBUS_SOCKET_ALLOW_HALF_OPEN);
s->flags.is_paused = 0;
s->flags.is_ipc = 0;
/* Link it into context so that timeout fires properly */
us_internal_socket_context_link_socket(s->context, s);

Expand Down Expand Up @@ -739,6 +742,7 @@ struct us_socket_t *us_socket_context_connect_unix(int ssl, struct us_socket_con
connect_socket->flags.low_prio_state = 0;
connect_socket->flags.allow_half_open = (options & LIBUS_SOCKET_ALLOW_HALF_OPEN);
connect_socket->flags.is_paused = 0;
connect_socket->flags.is_ipc = 0;
connect_socket->connect_state = NULL;
connect_socket->connect_next = NULL;
us_internal_socket_context_link_socket(context, connect_socket);
Expand Down Expand Up @@ -843,6 +847,14 @@ void us_socket_context_on_data(int ssl, struct us_socket_context_t *context, str
context->on_data = on_data;
}

void us_socket_context_on_fd(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_fd)(struct us_socket_t *s, int fd)) {
#ifndef LIBUS_NO_SSL
if (ssl) return;
#endif

context->on_fd = on_fd;
}

void us_socket_context_on_writable(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_writable)(struct us_socket_t *s)) {
#ifndef LIBUS_NO_SSL
if (ssl) {
Expand Down
11 changes: 5 additions & 6 deletions packages/bun-usockets/src/crypto/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1535,10 +1535,9 @@ us_internal_bun_create_ssl_socket_context(
/* Otherwise ee continue by creating a non-SSL context, but with larger ext to
* hold our SSL stuff */
struct us_internal_ssl_socket_context_t *context =
(struct us_internal_ssl_socket_context_t *)us_create_bun_socket_context(
0, loop,
sizeof(struct us_internal_ssl_socket_context_t) + context_ext_size,
options, err);
(struct us_internal_ssl_socket_context_t *)us_create_bun_nossl_socket_context(
loop,
sizeof(struct us_internal_ssl_socket_context_t) + context_ext_size);

/* I guess this is the only optional callback */
context->on_server_name = NULL;
Expand Down Expand Up @@ -2080,8 +2079,8 @@ struct us_internal_ssl_socket_t *us_internal_ssl_socket_wrap_with_tls(
us_socket_context_ref(0,old_context);

enum create_bun_socket_error_t err = CREATE_BUN_SOCKET_ERROR_NONE;
struct us_socket_context_t *context = us_create_bun_socket_context(
1, old_context->loop, sizeof(struct us_wrapped_socket_context_t),
struct us_socket_context_t *context = us_create_bun_ssl_socket_context(
old_context->loop, sizeof(struct us_wrapped_socket_context_t),
options, &err);

// Handle SSL context creation failure
Expand Down
3 changes: 3 additions & 0 deletions packages/bun-usockets/src/internal/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ struct us_socket_flags {
bool allow_half_open: 1;
/* 0 = not in low-prio queue, 1 = is in low-prio queue, 2 = was in low-prio queue in this iteration */
unsigned char low_prio_state: 2;
/* If true, the socket should be read using readmsg to support receiving file descriptors */
bool is_ipc: 1;

} __attribute__((packed));

Expand Down Expand Up @@ -287,6 +289,7 @@ struct us_socket_context_t {
struct us_socket_t *(*on_open)(struct us_socket_t *, int is_client, char *ip,
int ip_length);
struct us_socket_t *(*on_data)(struct us_socket_t *, char *data, int length);
struct us_socket_t *(*on_fd)(struct us_socket_t *, int fd);
struct us_socket_t *(*on_writable)(struct us_socket_t *);
struct us_socket_t *(*on_close)(struct us_socket_t *, int code, void *reason);
// void (*on_timeout)(struct us_socket_context *);
Expand Down
6 changes: 6 additions & 0 deletions packages/bun-usockets/src/internal/networking/bsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,13 @@ int bsd_addr_get_port(struct bsd_addr_t *addr);
LIBUS_SOCKET_DESCRIPTOR bsd_accept_socket(LIBUS_SOCKET_DESCRIPTOR fd, struct bsd_addr_t *addr);

ssize_t bsd_recv(LIBUS_SOCKET_DESCRIPTOR fd, void *buf, int length, int flags);
#if !defined(_WIN32)
ssize_t bsd_recvmsg(LIBUS_SOCKET_DESCRIPTOR fd, struct msghdr *msg, int flags);
#endif
ssize_t bsd_send(LIBUS_SOCKET_DESCRIPTOR fd, const char *buf, int length, int msg_more);
#if !defined(_WIN32)
ssize_t bsd_sendmsg(LIBUS_SOCKET_DESCRIPTOR fd, const struct msghdr *msg, int flags);
#endif
ssize_t bsd_write2(LIBUS_SOCKET_DESCRIPTOR fd, const char *header, int header_length, const char *payload, int payload_length);
int bsd_would_block();

Expand Down
8 changes: 6 additions & 2 deletions packages/bun-usockets/src/libusockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,10 @@ enum create_bun_socket_error_t {
CREATE_BUN_SOCKET_ERROR_INVALID_CA,
};

struct us_socket_context_t *us_create_bun_socket_context(int ssl, struct us_loop_t *loop,
struct us_socket_context_t *us_create_bun_ssl_socket_context(struct us_loop_t *loop,
int ext_size, struct us_bun_socket_context_options_t options, enum create_bun_socket_error_t *err);
struct us_socket_context_t *us_create_bun_nossl_socket_context(struct us_loop_t *loop,
int ext_size);

/* Delete resources allocated at creation time (will call unref now and only free when ref count == 0). */
void us_socket_context_free(int ssl, us_socket_context_r context) nonnull_fn_decl;
Expand All @@ -280,6 +282,8 @@ void us_socket_context_on_close(int ssl, us_socket_context_r context,
struct us_socket_t *(*on_close)(us_socket_r s, int code, void *reason));
void us_socket_context_on_data(int ssl, us_socket_context_r context,
struct us_socket_t *(*on_data)(us_socket_r s, char *data, int length));
void us_socket_context_on_fd(int ssl, us_socket_context_r context,
struct us_socket_t *(*on_fd)(us_socket_r s, int fd));
void us_socket_context_on_writable(int ssl, us_socket_context_r context,
struct us_socket_t *(*on_writable)(us_socket_r s));
void us_socket_context_on_timeout(int ssl, us_socket_context_r context,
Expand Down Expand Up @@ -465,7 +469,7 @@ void us_socket_local_address(int ssl, us_socket_r s, char *nonnull_arg buf, int

/* Bun extras */
struct us_socket_t *us_socket_pair(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR* fds);
struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR fd);
struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR fd, int ipc);
struct us_socket_t *us_socket_wrap_with_tls(int ssl, us_socket_r s, struct us_bun_socket_context_options_t options, struct us_socket_events_t events, int socket_ext_size);
int us_socket_raw_write(int ssl, us_socket_r s, const char *data, int length, int msg_more);
struct us_socket_t* us_socket_open(int ssl, struct us_socket_t * s, int is_client, char* ip, int ip_length);
Expand Down
39 changes: 38 additions & 1 deletion packages/bun-usockets/src/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int eof, in
s->flags.low_prio_state = 0;
s->flags.allow_half_open = listen_socket->s.flags.allow_half_open;
s->flags.is_paused = 0;
s->flags.is_ipc = 0;

/* We always use nodelay */
bsd_socket_nodelay(client_fd, 1);
Expand Down Expand Up @@ -391,7 +392,43 @@ void us_internal_dispatch_ready_poll(struct us_poll_t *p, int error, int eof, in
const int recv_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
#endif

int length = bsd_recv(us_poll_fd(&s->p), loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, LIBUS_RECV_BUFFER_LENGTH, recv_flags);
int length;
#if !defined(_WIN32)
if(s->flags.is_ipc) {
struct msghdr msg = {0};
struct iovec iov = {0};
char cmsg_buf[CMSG_SPACE(sizeof(int))];

iov.iov_base = loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING;
iov.iov_len = LIBUS_RECV_BUFFER_LENGTH;

msg.msg_flags = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_controllen = CMSG_LEN(sizeof(int));
msg.msg_control = cmsg_buf;

length = bsd_recvmsg(us_poll_fd(&s->p), &msg, recv_flags);

// Extract file descriptor if present
if (length > 0 && msg.msg_controllen > 0) {
struct cmsghdr *cmsg_ptr = CMSG_FIRSTHDR(&msg);
if (cmsg_ptr && cmsg_ptr->cmsg_level == SOL_SOCKET && cmsg_ptr->cmsg_type == SCM_RIGHTS) {
int fd = *(int *)CMSG_DATA(cmsg_ptr);
s = s->context->on_fd(s, fd);
if(us_socket_is_closed(0, s)) {
break;
}
}
}
}else{
#endif
length = bsd_recv(us_poll_fd(&s->p), loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, LIBUS_RECV_BUFFER_LENGTH, recv_flags);
#if !defined(_WIN32)
}
#endif

if (length > 0) {
s = s->context->on_data(s, loop->data.recv_buf + LIBUS_RECV_BUFFER_PADDING, length);
Expand Down
44 changes: 42 additions & 2 deletions packages/bun-usockets/src/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ struct us_socket_t *us_socket_pair(struct us_socket_context_t *ctx, int socket_e
return 0;
}

return us_socket_from_fd(ctx, socket_ext_size, fds[0]);
return us_socket_from_fd(ctx, socket_ext_size, fds[0], 0);
#endif
}

Expand All @@ -302,7 +302,7 @@ int us_socket_write2(int ssl, struct us_socket_t *s, const char *header, int hea
return written < 0 ? 0 : written;
}

struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR fd) {
struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR fd, int ipc) {
#if defined(LIBUS_USE_LIBUV) || defined(WIN32)
return 0;
#else
Expand All @@ -321,6 +321,8 @@ struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socke
s->flags.low_prio_state = 0;
s->flags.allow_half_open = 0;
s->flags.is_paused = 0;
s->flags.is_ipc = 0;
s->flags.is_ipc = ipc;
s->connect_state = NULL;

/* We always use nodelay */
Expand Down Expand Up @@ -374,6 +376,44 @@ int us_socket_write(int ssl, struct us_socket_t *s, const char *data, int length
return written < 0 ? 0 : written;
}

#if !defined(_WIN32)
/* Send a message with data and an attached file descriptor, for use in IPC. Returns the number of bytes written. If that
number is less than the length, the file descriptor was not sent. */
int us_socket_ipc_write_fd(struct us_socket_t *s, const char* data, int length, int fd) {
if (us_socket_is_closed(0, s) || us_socket_is_shut_down(0, s)) {
return 0;
}

struct msghdr msg = {0};
struct iovec iov = {0};
char cmsgbuf[CMSG_SPACE(sizeof(int))];

iov.iov_base = (void*)data;
iov.iov_len = length;

msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = CMSG_SPACE(sizeof(int));

struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));

*(int *)CMSG_DATA(cmsg) = fd;

int sent = bsd_sendmsg(us_poll_fd(&s->p), &msg, 0);

if (sent != length) {
s->context->loop->data.last_write_failed = 1;
us_poll_change(&s->p, s->context->loop, LIBUS_SOCKET_READABLE | LIBUS_SOCKET_WRITABLE);
}

return sent < 0 ? 0 : sent;
}
#endif

void *us_socket_ext(int ssl, struct us_socket_t *s) {
#ifndef LIBUS_NO_SSL
if (ssl) {
Expand Down
6 changes: 5 additions & 1 deletion packages/bun-uws/src/HttpContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,11 @@ struct HttpContext {
HttpContext *httpContext;

enum create_bun_socket_error_t err = CREATE_BUN_SOCKET_ERROR_NONE;
httpContext = (HttpContext *) us_create_bun_socket_context(SSL, (us_loop_t *) loop, sizeof(HttpContextData<SSL>), options, &err);
if constexpr (SSL) {
httpContext = (HttpContext *) us_create_bun_ssl_socket_context((us_loop_t *) loop, sizeof(HttpContextData<SSL>), options, &err);
} else {
httpContext = (HttpContext *) us_create_bun_nossl_socket_context((us_loop_t *) loop, sizeof(HttpContextData<SSL>));
}

if (!httpContext) {
return nullptr;
Expand Down
5 changes: 5 additions & 0 deletions src/Global.zig
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ pub fn exit(code: u32) noreturn {
// If we are crashing, allow the crash handler to finish it's work.
bun.crash_handler.sleepForeverIfAnotherThreadIsCrashing();

if (Environment.isDebug) {
bun.assert(bun.debug_allocator_data.backing.?.deinit() == .ok);
bun.debug_allocator_data.backing = null;
}

switch (Environment.os) {
.mac => std.c.exit(@bitCast(code)),
.windows => {
Expand Down
2 changes: 1 addition & 1 deletion src/bake/FrameworkRouter.zig
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ pub const Style = union(enum) {
if (is_optional and !is_catch_all)
return log.fail("Optional parameters can only be catch-all (change to \"[[...{s}]]\" or remove extra brackets)", .{param_name}, start, len);
// Potential future proofing
if (std.mem.indexOfAny(u8, param_name, "?*{}()=:#,")) |bad_char_index|
if (bun.strings.indexOfAny(param_name, "?*{}()=:#,")) |bad_char_index|
return log.fail("Parameter name cannot contain \"{c}\"", .{param_name[bad_char_index]}, start + bad_char_index, 1);

if (has_ending_double_bracket and !is_optional)
Expand Down
Loading