From 42e1c463fa93197a6d21f1630e6d675a429220c9 Mon Sep 17 00:00:00 2001 From: Christopher Kohlhoff Date: Wed, 9 Nov 2022 07:43:14 +1100 Subject: [PATCH] Fall back to fcntl if ioctl fails with ENOTTY when setting non-blocking mode. --- .../asio/detail/impl/descriptor_ops.ipp | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/asio/include/asio/detail/impl/descriptor_ops.ipp b/asio/include/asio/detail/impl/descriptor_ops.ipp index 5ba6a18aa0..1a2578a758 100644 --- a/asio/include/asio/detail/impl/descriptor_ops.ipp +++ b/asio/include/asio/detail/impl/descriptor_ops.ipp @@ -69,7 +69,18 @@ int close(int d, state_type& state, asio::error_code& ec) ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK); #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = 0; +# if defined(ENOTTY) + result = ::ioctl(d, FIONBIO, &arg); + get_last_error(ec, result < 0); + if (ec.value() == ENOTTY) + { + int flags = ::fcntl(d, F_GETFL, 0); + if (flags >= 0) + ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK); + } +# else // defined(ENOTTY) ::ioctl(d, FIONBIO, &arg); +# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) state &= ~non_blocking; @@ -103,6 +114,19 @@ bool set_user_non_blocking(int d, state_type& state, ioctl_arg_type arg = (value ? 1 : 0); int result = ::ioctl(d, FIONBIO, &arg); get_last_error(ec, result < 0); +# if defined(ENOTTY) + if (ec.value() == ENOTTY) + { + int result = ::fcntl(d, F_GETFL, 0); + get_last_error(ec, result < 0); + if (result >= 0) + { + int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK)); + result = ::fcntl(d, F_SETFL, flag); + get_last_error(ec, result < 0); + } + } +# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) if (result >= 0) @@ -153,6 +177,19 @@ bool set_internal_non_blocking(int d, state_type& state, ioctl_arg_type arg = (value ? 1 : 0); int result = ::ioctl(d, FIONBIO, &arg); get_last_error(ec, result < 0); +# if defined(ENOTTY) + if (ec.value() == ENOTTY) + { + int result = ::fcntl(d, F_GETFL, 0); + get_last_error(ec, result < 0); + if (result >= 0) + { + int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK)); + result = ::fcntl(d, F_SETFL, flag); + get_last_error(ec, result < 0); + } + } +# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) if (result >= 0)