libcutils: add android_get_control_socket() test

android_get_control_socket() checks if the resulting file descriptor
is valid, open and matches the socket bound name reference, which on
purpose will fail if a symbolic link is in the path rather than using
a fully qualified path.  If there are any non-alpha and non-numeric
characters in the name, they are replaced with _.  Add unit test.

Test: gTest libcutils_test --gtest_filter=SocketTest.android_get_control_socket
Bug: 32450474
Change-Id: I27a6419012033ef8bd6ca04f3e479d01264d8c49
diff --git a/libcutils/tests/sockets_test.cpp b/libcutils/tests/sockets_test.cpp
index 0f682a2..82961a4 100644
--- a/libcutils/tests/sockets_test.cpp
+++ b/libcutils/tests/sockets_test.cpp
@@ -18,10 +18,14 @@
 // IPv6 capabilities. These tests assume that no UDP packets are lost, which
 // should be the case for loopback communication, but is not guaranteed.
 
-#include <cutils/sockets.h>
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
 #include <time.h>
 
+#include <cutils/sockets.h>
 #include <gtest/gtest.h>
 
 // Makes sure the passed sockets are valid, sends data between them, and closes
@@ -185,3 +189,36 @@
 TEST(SocketsTest, TestSocketSendBuffersFailure) {
     EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0));
 }
+
+TEST(SocketsTest, android_get_control_socket) {
+    static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest.android_get_control_socket";
+    static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX);
+
+    EXPECT_EQ(unsetenv(key), 0);
+    EXPECT_EQ(android_get_control_socket(name), -1);
+
+    int fd;
+    ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0);
+    EXPECT_EQ(android_get_control_socket(name), -1);
+
+    struct sockaddr_un addr;
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name);
+    unlink(addr.sun_path);
+
+    EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0);
+    EXPECT_EQ(android_get_control_socket(name), -1);
+
+    char val[32];
+    snprintf(val, sizeof(val), "%d", fd);
+    EXPECT_EQ(setenv(key, val, true), 0);
+
+    EXPECT_EQ(android_get_control_socket(name), fd);
+    socket_close(fd);
+    EXPECT_EQ(android_get_control_socket(name), -1);
+    EXPECT_EQ(unlink(addr.sun_path), 0);
+    EXPECT_EQ(android_get_control_socket(name), -1);
+    EXPECT_EQ(unsetenv(key), 0);
+    EXPECT_EQ(android_get_control_socket(name), -1);
+}