From 9f8087d9209ea9553e494b9f3746fb63089da793 Mon Sep 17 00:00:00 2001 From: Calum MacRae Date: Sat, 27 Mar 2021 13:24:09 +0000 Subject: [PATCH] fix: Work around Big Sur read buffer tracking As noted by @koekeishiya on yabai#714, it seems a bug was introduced in Big Sur which causes `read` calls to track buffers incorrectly. These changes (taken from koekeishiya/yabai@4f8be49) work around this. Closes #41 --- makefile | 4 ++-- src/misc/socket.c | 13 +++++++++++++ src/spacebar.c | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/makefile b/makefile index 617e938..3ef71f4 100644 --- a/makefile +++ b/makefile @@ -4,10 +4,10 @@ BUILD_FLAGS = -std=c99 -Wall -DDEBUG -g -O0 -fvisibility=hidden -mmacosx-vers BUILD_PATH = ./bin DOC_PATH = ./doc SMP_PATH = ./examples -SPACEBAR_SRC = ./src/manifest.m +SPACEBAR_SRC = ./src/manifest.m BINS = $(BUILD_PATH)/spacebar -.PHONY: all clean install sign archive man +.PHONY: all clean install archive man all: clean $(BINS) diff --git a/src/misc/socket.c b/src/misc/socket.c index 3c9e521..8655031 100644 --- a/src/misc/socket.c +++ b/src/misc/socket.c @@ -14,6 +14,19 @@ char *socket_read(int sockfd, int *len) result = temp; memcpy(result+cursor, buffer, bytes_read); cursor += bytes_read; + + if (((result+cursor)[-1] == '\0') && + ((result+cursor)[-2] == '\0')) { + + // NOTE(cmacrae): if our message ends with double null-terminator we + // have successfully received the entire message. this was added because + // on macOS Big Sur we would in a few rare cases read the message AND YET + // still enter another call to *read* above that would block, because the + // client was finished sending its message and is blocking in a poll loop + // waiting for a response. + + break; + } } if (result && bytes_read != -1) { diff --git a/src/spacebar.c b/src/spacebar.c index 6c34685..643bc4f 100644 --- a/src/spacebar.c +++ b/src/spacebar.c @@ -54,7 +54,7 @@ static int client_send_message(int argc, char **argv) error("spacebar-msg: failed to connect to socket..\n"); } - int message_length = argc - 1; + int message_length = argc; int argl[argc]; for (int i = 1; i < argc; ++i) { @@ -70,6 +70,7 @@ static int client_send_message(int argc, char **argv) temp += argl[i]; *temp++ = '\0'; } + *temp++ = '\0'; if (!socket_write_bytes(sockfd, message, message_length)) { error("spacebar-msg: failed to send data..\n");