diff options
| author | Else <else@localhost> | 2026-04-10 13:18:18 +0200 |
|---|---|---|
| committer | frosty <gabriel@bwaaa.monster> | 2026-04-10 17:08:24 -0400 |
| commit | 80caa6b317fdde4f3223648da709d184438a5a08 (patch) | |
| tree | 1b08a7d9ee36548e28dff1851fea1e44f9abcec9 | |
| parent | cdb8f500f95ed6e5b752d361b403deb8d8dc1aac (diff) | |
| download | beaker-80caa6b317fdde4f3223648da709d184438a5a08.tar.gz | |
Fix client socket handling on macOS
| -rw-r--r-- | src/server.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/server.c b/src/server.c index 270be70..9c89f11 100644 --- a/src/server.c +++ b/src/server.c @@ -144,8 +144,9 @@ static int initialize_server_socket(const char *ip, int port, int *server_fd_out perror("setsockopt SO_REUSEADDR failed"); } - //Needed for FreeBSD Support - #ifdef SO_REUSEPORT + // Needed for FreeBSD support. On macOS this allows multiple processes to + // bind the same TCP port, which is surprising for a single-instance server. + #if defined(__FreeBSD__) && defined(SO_REUSEPORT) if (setsockopt(*server_fd_out, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt SO_REUSEPORT failed"); fprintf(stderr, "[ERROR] initialize_server_socket: Failed to set SO_REUSEPORT.\n"); @@ -184,6 +185,17 @@ static int initialize_server_socket(const char *ip, int port, int *server_fd_out return 0; } +static int set_socket_blocking(int fd) { + int flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + return -1; + + if ((flags & O_NONBLOCK) == 0) + return 0; + + return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); +} + void handle_client_connection(int new_socket) { current_client_socket = new_socket; char buffer[BUFFER_SIZE] = {0}; @@ -340,6 +352,11 @@ void beaker_run_with_threads(const char *ip, int port, int num_workers) { int new_socket; while ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) >= 0) { + if (set_socket_blocking(new_socket) < 0) { + perror("fcntl clear O_NONBLOCK failed"); + close(new_socket); + continue; + } if (work_queue_push(&g_work_queue, new_socket) < 0) { fprintf(stderr, "[WARNING] Work queue full, closing connection\n"); const char *busy_response = "HTTP/1.1 503 Service Unavailable\r\nContent-Length: 0\r\n\r\n"; |
