aboutsummaryrefslogtreecommitdiff
path: root/ssh-agent-filter.C
diff options
context:
space:
mode:
authorTimo Weingärtner <timo@tiwe.de>2021-05-17 12:37:22 +0200
committerTimo Weingärtner <timo@tiwe.de>2026-03-07 22:25:16 +0100
commit3088eda994ea0812e4aebf414334304723108671 (patch)
tree76ccf182aafda3bcbebbbfc151148931df2c2c49 /ssh-agent-filter.C
parent2927e78b226ede4df9d6eee9701485ed32c8d48a (diff)
downloadssh-agent-filter-3088eda994ea0812e4aebf414334304723108671.tar.gz
factor out alter_fd_flags()
this also saves one syscall each time the flags are already as they should be
Diffstat (limited to 'ssh-agent-filter.C')
-rw-r--r--ssh-agent-filter.C25
1 files 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 <int write_cmd, int set_flags, int clear_flags>
+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<F_SETFD, FD_CLOEXEC, 0>(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<F_SETFL, O_NONBLOCK, 0>(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<F_SETFL, 0, O_NONBLOCK>(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<F_SETFD, FD_CLOEXEC, 0>(client_sock);
}
std::thread t{handle_client, client_sock};
t.detach();