From 3088eda994ea0812e4aebf414334304723108671 Mon Sep 17 00:00:00 2001 From: Timo Weingärtner Date: Mon, 17 May 2021 12:37:22 +0200 Subject: factor out alter_fd_flags() this also saves one syscall each time the flags are already as they should be --- ssh-agent-filter.C | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/ssh-agent-filter.C b/ssh-agent-filter.C index fbeb85f..61255a0 100644 --- a/ssh-agent-filter.C +++ b/ssh-agent-filter.C @@ -121,8 +121,19 @@ string base64_encode (string const & s) { return {begin(b64), end(b64)}; } -void cloexec (int fd) { - if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC)) +template +void alter_fd_flags (int const fd) { + static_assert(write_cmd == F_SETFD || write_cmd == F_SETFL, "unsupported fcntl() operation"); + constexpr int read_cmd = (write_cmd == F_SETFD) ? F_GETFD : F_GETFL; + static_assert((set_flags & clear_flags) == 0, "overlap in set and clear"); + + int const current_flags = fcntl(fd, read_cmd); + if (current_flags == -1) + throw system_error(errno, system_category(), "fcntl"); + int const new_flags = (current_flags | set_flags) & ~clear_flags; + if (current_flags == new_flags) + return; + if (fcntl(fd, write_cmd, new_flags)) throw system_error(errno, system_category(), "fcntl"); } @@ -131,7 +142,7 @@ int make_cloexec_socket (int const address_family, int const type, int const pro std::lock_guard lock{fd_fork_mutex}; if ((sock = socket(address_family, type | SOCK_CLOEXEC, protocol)) == -1) throw system_error(errno, system_category(), "socket"); - cloexec(sock); + alter_fd_flags(sock); return sock; } @@ -163,8 +174,7 @@ int make_upstream_agent_conn () { int make_listen_sock () { int const sock = make_cloexec_socket(AF_UNIX, SOCK_STREAM, 0); - if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK)) - throw system_error(errno, system_category(), "fcntl"); + alter_fd_flags(sock); struct sockaddr_un addr{AF_UNIX, {}}; @@ -555,8 +565,7 @@ rfc4251::string handle_request (rfc4251::string const & r) { } void handle_client (int const sock) try { - if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) & ~O_NONBLOCK)) - throw system_error(errno, system_category(), "fcntl"); + alter_fd_flags(sock); // we could use only one streambuf and iostream but when // switching from read to write an lseek call is made that @@ -633,7 +642,7 @@ int main (int const argc, char const * const * const argv) { else break; } - cloexec(client_sock); + alter_fd_flags(client_sock); } std::thread t{handle_client, client_sock}; t.detach(); -- cgit v1.2.3