build(core): fix emulator build on macOS
What changed, and why it matters
This commit fixes the Trezor emulator build on macOS. It replaces Linux-only socket flags (SOCK_NONBLOCK and MSG_DONTWAIT) with portable equivalents that work on both Linux and macOS. The socket is still set to non-blocking mode using fcntl, and the send/receive calls now rely on that non-blocking state instead of per-call flags. There is no security-relevant change.
No security action needed. Treat as a normal build/portability fix.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change is in core/embed/io/usb/unix/sock.c, which implements UDP socket handling for the Unix-based Trezor emulator. macOS does not define SOCK_NONBLOCK or MSG_DONTWAIT, so the build failed there. The patch removes SOCK_NONBLOCK from socket() and instead uses F_GETFL/F_SETFL to add O_NONBLOCK. It also removes MSG_DONTWAIT from sendto() and recvfrom(), relying on the already non-blocking file descriptor. Functionally equivalent behavior is preserved; this is a portability/build fix only.
Changed components
core/embed/io/usb/unix/sock.cInspect captured patch +6 / −5
diff --git a/core/embed/io/usb/unix/sock.c b/core/embed/io/usb/unix/sock.c
index ecf9a36e7..298fa0af4 100644
--- a/core/embed/io/usb/unix/sock.c
+++ b/core/embed/io/usb/unix/sock.c
@@ -10,11 +10,12 @@ void sock_init(emu_sock_t *sock) {
void sock_start(emu_sock_t *sock, const char *ip, uint16_t port) {
sock->port = port;
- sock->sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
+ sock->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ensure(sectrue * (sock->sock >= 0), NULL);
- int ret = fcntl(sock->sock, F_SETFL, O_NONBLOCK);
+ int flags = fcntl(sock->sock, F_GETFL, 0);
+ int ret = fcntl(sock->sock, F_SETFL, flags | O_NONBLOCK);
ensure(sectrue * (ret != -1), NULL);
sock->si_me.sin_family = AF_INET;
@@ -54,7 +55,7 @@ bool sock_can_recv(emu_sock_t *sock) {
ssize_t sock_sendto(emu_sock_t *sock, const void *data, size_t len) {
if (sock->slen > 0) {
- ssize_t r = sendto(sock->sock, data, len, MSG_DONTWAIT,
+ ssize_t r = sendto(sock->sock, data, len, 0,
(const struct sockaddr *)&(sock->si_other), sock->slen);
if (r != len) {
return -1;
@@ -68,8 +69,8 @@ ssize_t sock_recvfrom(emu_sock_t *sock, uint8_t *data, size_t max_len) {
struct sockaddr_in si;
socklen_t sl = sizeof(si);
memset(data, 0, max_len);
- ssize_t r = recvfrom(sock->sock, data, max_len, MSG_DONTWAIT,
- (struct sockaddr *)&si, &sl);
+ ssize_t r =
+ recvfrom(sock->sock, data, max_len, 0, (struct sockaddr *)&si, &sl);
if (r <= 0) {
return 0;
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.