[vm,dart:io] On Linux, Android, and Fuchsia the getsockopt parameter
is incorrect.

Fixes breakage caused by https://dart-review.googlesource.com/c/sdk/+/89164

Change-Id: I2c6842a20930cc43247dacd4d62b0cd53d58ac95
Reviewed-on: https://dart-review.googlesource.com/c/90142
Commit-Queue: Zach Anderson <zra@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
diff --git a/runtime/bin/socket_base_android.cc b/runtime/bin/socket_base_android.cc
index c1ed4f4..83f400b 100644
--- a/runtime/bin/socket_base_android.cc
+++ b/runtime/bin/socket_base_android.cc
@@ -363,7 +363,10 @@
                            int option,
                            char* data,
                            unsigned int* length) {
-  return NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, length)) == 0;
+  socklen_t optlen = static_cast<socklen_t>(*length);
+  auto result = NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, &optlen));
+  *length = static_cast<unsigned int>(optlen);
+  return result == 0;
 }
 
 bool SocketBase::JoinMulticast(intptr_t fd,
diff --git a/runtime/bin/socket_base_fuchsia.cc b/runtime/bin/socket_base_fuchsia.cc
index d90a48c..7191a64 100644
--- a/runtime/bin/socket_base_fuchsia.cc
+++ b/runtime/bin/socket_base_fuchsia.cc
@@ -9,10 +9,10 @@
 
 // TODO(ZX-766): If/when Fuchsia adds getifaddrs(), use that instead of the
 // ioctl in netconfig.h.
-#include <errno.h>  // NOLINT
-#include <fcntl.h>  // NOLINT
+#include <errno.h>    // NOLINT
+#include <fcntl.h>    // NOLINT
+#include <ifaddrs.h>  // NOLINT
 #include <lib/netstack/c/netconfig.h>
-#include <ifaddrs.h>      // NOLINT
 #include <net/if.h>       // NOLINT
 #include <netinet/tcp.h>  // NOLINT
 #include <stdio.h>        // NOLINT
@@ -391,8 +391,11 @@
                            char* data,
                            unsigned int* length) {
   IOHandle* handle = reinterpret_cast<IOHandle*>(fd);
-  return NO_RETRY_EXPECTED(
-             getsockopt(handle->fd(), level, option, data, length)) == 0;
+  socklen_t optlen = static_cast<socklen_t>(*length);
+  auto result =
+      NO_RETRY_EXPECTED(getsockopt(handle->fd(), level, option, data, &optlen));
+  *length = static_cast<unsigned int>(optlen);
+  return result == 0;
 }
 
 bool SocketBase::JoinMulticast(intptr_t fd,
diff --git a/runtime/bin/socket_base_linux.cc b/runtime/bin/socket_base_linux.cc
index 37c7530..2e6b461 100644
--- a/runtime/bin/socket_base_linux.cc
+++ b/runtime/bin/socket_base_linux.cc
@@ -404,7 +404,10 @@
                            int option,
                            char* data,
                            unsigned int* length) {
-  return NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, length)) == 0;
+  socklen_t optlen = static_cast<socklen_t>(*length);
+  auto result = NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, &optlen));
+  *length = static_cast<unsigned int>(optlen);
+  return result == 0;
 }
 
 bool SocketBase::JoinMulticast(intptr_t fd,