From 51e6dceb20c82345339840c5e4de7e87399e8246 Mon Sep 17 00:00:00 2001 From: DavidPetkovsek Date: Tue, 24 Mar 2026 11:50:38 -0400 Subject: [PATCH 1/2] set FE_CLOEXEC for socket FDs on non-windows builds --- include/crow/http_server.h | 24 +++++++++++++++++++----- include/crow/socket_acceptors.h | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/include/crow/http_server.h b/include/crow/http_server.h index e5cff67a1..a0655dcb3 100644 --- a/include/crow/http_server.h +++ b/include/crow/http_server.h @@ -1,5 +1,9 @@ #pragma once +#ifndef _WIN32 +#include +#include +#endif #ifdef CROW_USE_BOOST #include #ifdef CROW_ENABLE_SSL @@ -46,7 +50,7 @@ namespace crow // NOTE: Already documented in "crow/app.h" { public: Server(Handler* handler, - typename Acceptor::endpoint endpoint, + typename Acceptor::endpoint endpoint, std::string server_name = std::string("Crow/") + VERSION, std::tuple* middlewares = nullptr, unsigned int concurrency = 1, @@ -77,6 +81,12 @@ namespace crow // NOTE: Already documented in "crow/app.h" return; } + if(set_cloexec(acceptor_.raw_acceptor().native_handle()) == -1){ + CROW_LOG_ERROR << "Failed to set FD_CLOEXEC on start: " << std::strerror(errno); + startup_failed_ = true; + return; + } + acceptor_.raw_acceptor().set_option(Acceptor::reuse_address_option(), ec); if (ec) { CROW_LOG_ERROR << "Failed to set socket option: " << ec.message(); @@ -202,8 +212,8 @@ namespace crow // NOTE: Already documented in "crow/app.h" } handler_->port(acceptor_.port()); handler_->address_is_bound(); - CROW_LOG_INFO << server_name_ - << " server is running at " << acceptor_.url_display(handler_->ssl_used()) + CROW_LOG_INFO << server_name_ + << " server is running at " << acceptor_.url_display(handler_->ssl_used()) << " using " << concurrency_ << " threads"; CROW_LOG_INFO << "Call `app.loglevel(crow::LogLevel::Warning)` to hide Info level logs."; @@ -257,7 +267,7 @@ namespace crow // NOTE: Already documented in "crow/app.h" io_context_.stop(); // Close main io_service } - + uint16_t port() const { return acceptor_.local_endpoint().port(); } @@ -310,7 +320,7 @@ namespace crow // NOTE: Already documented in "crow/app.h" auto p = std::make_shared>( ic, handler_, server_name_, middlewares_, get_cached_date_str_pool_[context_idx], *task_timer_pool_[context_idx], adaptor_ctx_, task_queue_length_pool_[context_idx]); - + CROW_LOG_DEBUG << &ic << " {" << context_idx << "} queue length: " << task_queue_length_pool_[context_idx]; acceptor_.raw_acceptor().async_accept( @@ -318,6 +328,10 @@ namespace crow // NOTE: Already documented in "crow/app.h" [this, p, &ic](error_code ec) { if (!ec) { + if(set_cloexec(p->socket().native_handle()) == -1){ + CROW_LOG_ERROR << "Failed to set FD_CLOEXEC on accepted socket: " << std::strerror(errno); + } + asio::post(ic, [p] { p->start(); diff --git a/include/crow/socket_acceptors.h b/include/crow/socket_acceptors.h index 06afacb11..a6acce7a2 100644 --- a/include/crow/socket_acceptors.h +++ b/include/crow/socket_acceptors.h @@ -1,4 +1,7 @@ #pragma once +#ifndef _WIN32 +#include +#endif #ifdef CROW_USE_BOOST #include #ifdef CROW_ENABLE_SSL @@ -18,6 +21,24 @@ namespace crow { + /// Set FD_CLOEXEC on a native socket handle to prevent file descriptor leaking across fork/exec. + template + inline int set_cloexec([[maybe_unused]] NativeHandle fd) + { +#ifndef _WIN32 + int flags = fcntl(fd, F_GETFD); + if (flags != -1) + { + return fcntl(fd, F_SETFD, flags | FD_CLOEXEC); + } + // Retrieving current flags failed + return flags; +#else + // Return not -1 (following fcntl()'s docs) + return 0; +#endif + } + #ifdef CROW_USE_BOOST namespace asio = boost::asio; using error_code = boost::system::error_code; From f712c7068444cada13ea32c7b796316cca3d6d16 Mon Sep 17 00:00:00 2001 From: DavidPetkovsek Date: Tue, 24 Mar 2026 12:30:48 -0400 Subject: [PATCH 2/2] Fix includes for non-windows builds --- include/crow/http_server.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/crow/http_server.h b/include/crow/http_server.h index a0655dcb3..082df4298 100644 --- a/include/crow/http_server.h +++ b/include/crow/http_server.h @@ -1,9 +1,5 @@ #pragma once -#ifndef _WIN32 -#include -#include -#endif #ifdef CROW_USE_BOOST #include #ifdef CROW_ENABLE_SSL @@ -20,8 +16,10 @@ #endif #include +#include #include #include +#include #include #include #include