Darwin: fix sockaddr_un sun_len causing silent WRITE_START drops#789
Open
jverkoey wants to merge 1 commit intodrolbr:masterfrom
Open
Darwin: fix sockaddr_un sun_len causing silent WRITE_START drops#789jverkoey wants to merge 1 commit intodrolbr:masterfrom
jverkoey wants to merge 1 commit intodrolbr:masterfrom
Conversation
The AF_UNIX sun_len field on Darwin is the *total sockaddr struct* length used, not the path length. The current value 'socket_name.size() + 1' is still 1 byte short -- on Darwin the struct layout is: uint8_t sun_len; // 1 byte sa_family_t sun_family; // 1 byte char sun_path[]; // strlen(path) bytes so the portable SUN_LEN macro expands to strlen(path) + 2. Symptom of the off-by-one: update_from_dir's Dispatcher_Client::write_start() would block in select() forever waiting for a WRITE_START ack from the dispatcher. The dispatcher never logged receiving the request -- the kernel silently dropped the message because the sockaddr length header was inconsistent. Reads via the shm + query connections worked because the read protocol does less work on the sockaddr and the mismatch wasn't fatal there. Use the portable SUN_LEN(&local) macro: sizeof(sockaddr_un) - sizeof(sun_path) + strlen(sun_path) On Darwin that expands to strlen(path) + 2, matching what the kernel expects. SUN_LEN is defined in sys/un.h on Darwin, *BSD, and Linux.
This was referenced Apr 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Darwin
struct sockaddr_unhas asun_lenfield that the kernel reads as the total length of the sockaddr struct currently in use (the byte that precedessun_familyon BSD-derived socket APIs), not the length of the path. The current valuesocket_name.size() + 1is 1 byte short — the Darwin layout is:so the portable
SUN_LENmacro (defined insys/un.hon Darwin, *BSD, and Linux) expands tostrlen(path) + 2.Symptom
update_from_dir'sDispatcher_Client::write_start()blocks inselect()indefinitely waiting for aWRITE_STARTack from the dispatcher. The dispatcher never logs receiving the request — the kernel silently drops the message because the sockaddr length header is inconsistent. Reads via the shm + query connections still work because the read protocol does less work on the sockaddr and the off-by-one isn't fatal there; only writes trigger the breakage.Fix
Use the portable
SUN_LEN(&local)macro instead of a hand-computed length. Header definition:On Darwin that expands to
strlen(path) + 2, matching what the kernel expects.Reproducer
Native build of osm-3s on Apple Silicon (macOS 26). Dispatcher starts, serves read queries fine. Any invocation of
update_from_dir(including viaapply_osc_to_db.sh) hangs on startup. Dispatcher'sdatabase.logshows nowrite_start of process Nline for the caller.Verified fixed by applying this patch:
update_from_dircompletes cleanly and the dispatcher immediately logswrite_start of process Non the next attempt.Companion PRs: #788 (off64_t alias), #790 (Mmap → pread).