From: Mike Brady <4265913+mikebrady@users.noreply.github.com> Date: Tue, 9 Dec 2025 17:13:18 +0000 (+0000) Subject: Add a check for EINTR to accept() calls. X-Git-Tag: 5.0-post-dev~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=489bfd7862594a286e5238304c11955c58c74ff7;p=thirdparty%2Fshairport-sync.git Add a check for EINTR to accept() calls. --- diff --git a/Makefile.am b/Makefile.am index 35603caf..6325a438 100644 --- a/Makefile.am +++ b/Makefile.am @@ -27,7 +27,7 @@ noinst_LIBRARIES = # See below for the flags for the test client program -shairport_sync_SOURCES = utilities/debug.c shairport.c bonjour_strings.c rtsp.c mdns.c common.c rtp.c player.c audio.c loudness.c activity_monitor.c +shairport_sync_SOURCES = shairport.c bonjour_strings.c rtsp.c mdns.c common.c rtp.c player.c audio.c loudness.c activity_monitor.c utilities/debug.c utilities/network_utilities.c if BUILD_FOR_DARWIN AM_CXXFLAGS = -I/usr/local/include -Wno-multichar -Wall -Wextra -Wno-deprecated-declarations -pthread -DSYSCONFDIR=\"$(sysconfdir)\" diff --git a/ap2_event_receiver.c b/ap2_event_receiver.c index c4d939e8..75371cbd 100644 --- a/ap2_event_receiver.c +++ b/ap2_event_receiver.c @@ -31,6 +31,7 @@ #include "ptp-utilities.h" #include "rtsp.h" #include "utilities/structured_buffer.h" +#include "utilities/network_utilities.h" void ap2_event_receiver_cleanup_handler(void *arg) { rtsp_conn_info *conn = (rtsp_conn_info *)arg; @@ -108,7 +109,7 @@ void *ap2_event_receiver(void *arg) { memset(&remote_addr, 0, sizeof(remote_addr)); socklen_t addr_size = sizeof(remote_addr); - int fd = accept(conn->event_socket, (struct sockaddr *)&remote_addr, &addr_size); + int fd = eintr_checked_accept(conn->event_socket, (struct sockaddr *)&remote_addr, &addr_size); debug(2, "Connection %d: ap2_event_receiver accepted a connection on socket %d and moved to a new " "socket %d.", @@ -194,9 +195,11 @@ void *ap2_event_receiver(void *arg) { } } while (finished == 0); + debug(3, "Connection %d: AP2 Event Receiver RTP thread starting \"normal\" exit.", conn->connection_number); pthread_cleanup_pop(1); // close the socket + pthread_cleanup_pop(1); // do the cleanup pthread_cleanup_pop(1); // delete the structured buffer debug(2, "Connection %d: AP2 Event Receiver RTP thread \"normal\" exit.", diff --git a/ap2_rc_event_receiver.c b/ap2_rc_event_receiver.c index 587d375c..74d03327 100644 --- a/ap2_rc_event_receiver.c +++ b/ap2_rc_event_receiver.c @@ -29,6 +29,7 @@ #include "player.h" #include "rtsp.h" #include "utilities/structured_buffer.h" +#include "utilities/network_utilities.h" void ap2_rc_event_receiver_cleanup_handler(void *arg) { rtsp_conn_info *conn = (rtsp_conn_info *)arg; @@ -58,7 +59,7 @@ void *ap2_rc_event_receiver(void *arg) { memset(&remote_addr, 0, sizeof(remote_addr)); socklen_t addr_size = sizeof(remote_addr); - int fd = accept(conn->event_socket, (struct sockaddr *)&remote_addr, &addr_size); + int fd = eintr_checked_accept(conn->event_socket, (struct sockaddr *)&remote_addr, &addr_size); debug(2, "Connection %d: ap2_rc_event_receiver accepted a connection on socket %d and moved to a " "new " diff --git a/rtsp.c b/rtsp.c index 0b76004b..30a7f54a 100644 --- a/rtsp.c +++ b/rtsp.c @@ -112,6 +112,7 @@ #endif #include "mdns.h" +#include "utilities/network_utilities.h" #define METADATA_SNDBUF (4 * 1024 * 1024) @@ -457,7 +458,7 @@ play_lock_r get_play_lock(rtsp_conn_info *conn, int allow_session_interruption) // important -- demote the principal conn before cancelling it if (principal_conn->fd > 0) { debug(2, - "Connection %d: %s has acquired play_lock and is forcing termination of Connection " + "Connection %d: %s is acquiring play_lock and is forcing termination of Connection " "%d %s. Closing " "RTSP connection socket %d: " "from %s:%u to self at " @@ -491,7 +492,7 @@ play_lock_r get_play_lock(rtsp_conn_info *conn, int allow_session_interruption) #endif response = play_lock_acquired_by_breaking_in; } - usleep(1000000); // don't know why this delay is needed. + // usleep(1000000); // don't know why this delay is needed. } if ((principal_conn != NULL) && (response != play_lock_already_acquired)) debug(1, "Connection %d: %s has principal_conn.", conn->connection_number, @@ -5410,7 +5411,7 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) { #endif socklen_t size_of_reply = sizeof(SOCKADDR); - conn->fd = accept(acceptfd, (struct sockaddr *)&conn->remote, &size_of_reply); + conn->fd = eintr_checked_accept(acceptfd, (struct sockaddr *)&conn->remote, &size_of_reply); if (conn->fd < 0) { debug(1, "Connection %d: New connection on port %d not accepted:", conn->connection_number, config.port); diff --git a/utilities/network_utilities.c b/utilities/network_utilities.c new file mode 100644 index 00000000..81c01693 --- /dev/null +++ b/utilities/network_utilities.c @@ -0,0 +1,47 @@ +/* + * Network Utilities. This file is part of Shairport Sync. + * Copyright (c) Mike Brady 2014--2025 + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "network_utilities.h" + +int eintr_checked_accept(int sockfd, struct sockaddr *addr, + socklen_t *addrlen) { + int response; + do { + response = accept(sockfd, addr, addrlen); + + if (response == -1) { + char errorstring[1024]; + strerror_r(errno, (char *)errorstring, sizeof(errorstring)); + debug(1, + "error %d accept()ing a socketin ap2_event_receiver %d: \"%s\". Error %d is ignored.", + errno, errorstring, EINTR); + } + + } while((response == -1) && (errno == EINTR)); + return response; +} \ No newline at end of file diff --git a/utilities/network_utilities.h b/utilities/network_utilities.h new file mode 100644 index 00000000..001a1c95 --- /dev/null +++ b/utilities/network_utilities.h @@ -0,0 +1,10 @@ +#ifndef _NETWORK_UTILITIES_H +#define _NETWORK_UTILITIES_H + +#include + +#define restrict + +int eintr_checked_accept(int sockfd, struct sockaddr *addr, + socklen_t *addrlen); +#endif // _NETWORK_UTILITIES_H