[libc-commits] [libc] [libc] Implement getsockname and getpeername (PR #197196)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Tue May 12 06:42:48 PDT 2026


https://github.com/labath created https://github.com/llvm/llvm-project/pull/197196

This patch implements getsockname and getpeername functions for Linux, and adds unit tests to verify them under connected, unbound, and invalid socket states.

The implementations do not have the socketcall fallbacks, as those are being removed in #197189.

>From 963a98453009fd1ff61512d02ba839204e977e95 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Thu, 7 May 2026 11:17:38 +0000
Subject: [PATCH] [libc] Implement getsockname and getpeername

This patch implements getsockname and getpeername functions for Linux,
and adds unit tests to verify them under connected, unbound, and invalid
socket states.
---
 libc/config/linux/aarch64/entrypoints.txt     |   2 +
 libc/config/linux/riscv/entrypoints.txt       |   2 +
 libc/config/linux/x86_64/entrypoints.txt      |   2 +
 libc/include/sys/socket.yaml                  |  16 ++
 .../linux/syscall_wrappers/CMakeLists.txt     |  26 +++
 .../linux/syscall_wrappers/getpeername.h      |  39 +++++
 .../linux/syscall_wrappers/getsockname.h      |  39 +++++
 libc/src/sys/socket/CMakeLists.txt            |  14 ++
 libc/src/sys/socket/getpeername.h             |  28 ++++
 libc/src/sys/socket/getsockname.h             |  28 ++++
 libc/src/sys/socket/linux/CMakeLists.txt      |  30 ++++
 libc/src/sys/socket/linux/getpeername.cpp     |  35 ++++
 libc/src/sys/socket/linux/getsockname.cpp     |  35 ++++
 libc/test/src/sys/socket/linux/CMakeLists.txt |  26 +++
 .../src/sys/socket/linux/sockname_test.cpp    | 156 ++++++++++++++++++
 15 files changed, 478 insertions(+)
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/getpeername.h
 create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/getsockname.h
 create mode 100644 libc/src/sys/socket/getpeername.h
 create mode 100644 libc/src/sys/socket/getsockname.h
 create mode 100644 libc/src/sys/socket/linux/getpeername.cpp
 create mode 100644 libc/src/sys/socket/linux/getsockname.cpp
 create mode 100644 libc/test/src/sys/socket/linux/sockname_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 0c8fb3c8dbc15..dce227d0402b2 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -287,6 +287,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.socket.accept4
     libc.src.sys.socket.bind
     libc.src.sys.socket.connect
+    libc.src.sys.socket.getpeername
+    libc.src.sys.socket.getsockname
     libc.src.sys.socket.getsockopt
     libc.src.sys.socket.listen
     libc.src.sys.socket.recv
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 99a5c820159f8..1fac13a0b5dbc 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -287,6 +287,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.socket.accept4
     libc.src.sys.socket.bind
     libc.src.sys.socket.connect
+    libc.src.sys.socket.getpeername
+    libc.src.sys.socket.getsockname
     libc.src.sys.socket.getsockopt
     libc.src.sys.socket.listen
     libc.src.sys.socket.recv
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 45fdde6454880..43e5885e1920e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -303,6 +303,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.socket.accept4
     libc.src.sys.socket.bind
     libc.src.sys.socket.connect
+    libc.src.sys.socket.getpeername
+    libc.src.sys.socket.getsockname
     libc.src.sys.socket.getsockopt
     libc.src.sys.socket.listen
     libc.src.sys.socket.recv
diff --git a/libc/include/sys/socket.yaml b/libc/include/sys/socket.yaml
index b1a1a2adb7ebe..e488bb9e43353 100644
--- a/libc/include/sys/socket.yaml
+++ b/libc/include/sys/socket.yaml
@@ -51,6 +51,22 @@ functions:
       - type: int
       - type: const struct sockaddr *
       - type: socklen_t
+  - name: getpeername
+    standards:
+      - POSIX
+    return_type: int
+    arguments:
+      - type: int
+      - type: struct sockaddr *__restrict
+      - type: socklen_t *__restrict
+  - name: getsockname
+    standards:
+      - POSIX
+    return_type: int
+    arguments:
+      - type: int
+      - type: struct sockaddr *__restrict
+      - type: socklen_t *__restrict
   - name: getsockopt
     standards:
       - POSIX
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index bbe76fece3bdd..8219d0998873b 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -94,6 +94,32 @@ add_header_library(
     libc.include.sys_syscall
 )
 
+add_header_library(
+  getpeername
+  HDRS
+    getpeername.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.types.socklen_t
+    libc.hdr.types.struct_sockaddr
+    libc.include.sys_syscall
+)
+
+add_header_library(
+  getsockname
+  HDRS
+    getsockname.h
+  DEPENDS
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.hdr.types.socklen_t
+    libc.hdr.types.struct_sockaddr
+    libc.include.sys_syscall
+)
+
 add_header_library(
   listen
   HDRS
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getpeername.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getpeername.h
new file mode 100644
index 0000000000000..20c51d51da946
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getpeername.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for getpeername.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPEERNAME_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPEERNAME_H
+
+#include "hdr/types/socklen_t.h"
+#include "hdr/types/struct_sockaddr.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> getpeername(int sockfd, struct sockaddr *addr,
+                                     socklen_t *addrlen) {
+  int ret = syscall_impl<int>(SYS_getpeername, sockfd, addr, addrlen);
+  if (ret < 0)
+    return Error(-static_cast<int>(ret));
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETPEERNAME_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getsockname.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getsockname.h
new file mode 100644
index 0000000000000..6069fc58c5816
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getsockname.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Syscall wrapper for getsockname.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETSOCKNAME_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETSOCKNAME_H
+
+#include "hdr/types/socklen_t.h"
+#include "hdr/types/struct_sockaddr.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> getsockname(int sockfd, struct sockaddr *addr,
+                                     socklen_t *addrlen) {
+  int ret = syscall_impl<int>(SYS_getsockname, sockfd, addr, addrlen);
+  if (ret < 0)
+    return Error(-static_cast<int>(ret));
+  return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETSOCKNAME_H
diff --git a/libc/src/sys/socket/CMakeLists.txt b/libc/src/sys/socket/CMakeLists.txt
index b602ab99c8a9d..a100e90fe3f2d 100644
--- a/libc/src/sys/socket/CMakeLists.txt
+++ b/libc/src/sys/socket/CMakeLists.txt
@@ -37,6 +37,20 @@ add_entrypoint_object(
     .${LIBC_TARGET_OS}.connect
 )
 
+add_entrypoint_object(
+  getpeername
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.getpeername
+)
+
+add_entrypoint_object(
+  getsockname
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.getsockname
+)
+
 add_entrypoint_object(
   getsockopt
   ALIAS
diff --git a/libc/src/sys/socket/getpeername.h b/libc/src/sys/socket/getpeername.h
new file mode 100644
index 0000000000000..4e7fddd738337
--- /dev/null
+++ b/libc/src/sys/socket/getpeername.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for getpeername.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_SOCKET_GETPEERNAME_H
+#define LLVM_LIBC_SRC_SYS_SOCKET_GETPEERNAME_H
+
+#include "hdr/types/socklen_t.h"
+#include "hdr/types/struct_sockaddr.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int getpeername(int sockfd, struct sockaddr *__restrict addr,
+                socklen_t *__restrict addrlen);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_SOCKET_GETPEERNAME_H
diff --git a/libc/src/sys/socket/getsockname.h b/libc/src/sys/socket/getsockname.h
new file mode 100644
index 0000000000000..e9520932bec8f
--- /dev/null
+++ b/libc/src/sys/socket/getsockname.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for getsockname.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_SOCKET_GETSOCKNAME_H
+#define LLVM_LIBC_SRC_SYS_SOCKET_GETSOCKNAME_H
+
+#include "hdr/types/socklen_t.h"
+#include "hdr/types/struct_sockaddr.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int getsockname(int sockfd, struct sockaddr *__restrict addr,
+                socklen_t *__restrict addrlen);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_SOCKET_GETSOCKNAME_H
diff --git a/libc/src/sys/socket/linux/CMakeLists.txt b/libc/src/sys/socket/linux/CMakeLists.txt
index e39345410e879..c86991a3e42ea 100644
--- a/libc/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/src/sys/socket/linux/CMakeLists.txt
@@ -66,6 +66,36 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  getpeername
+  SRCS
+    getpeername.cpp
+  HDRS
+    ../getpeername.h
+  DEPENDS
+    libc.include.sys_socket
+    libc.src.__support.OSUtil.osutil
+    libc.hdr.types.struct_sockaddr
+    libc.hdr.types.socklen_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.getpeername
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  getsockname
+  SRCS
+    getsockname.cpp
+  HDRS
+    ../getsockname.h
+  DEPENDS
+    libc.include.sys_socket
+    libc.src.__support.OSUtil.osutil
+    libc.hdr.types.struct_sockaddr
+    libc.hdr.types.socklen_t
+    libc.src.__support.OSUtil.linux.syscall_wrappers.getsockname
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   getsockopt
   SRCS
diff --git a/libc/src/sys/socket/linux/getpeername.cpp b/libc/src/sys/socket/linux/getpeername.cpp
new file mode 100644
index 0000000000000..8e19f5bbc3f94
--- /dev/null
+++ b/libc/src/sys/socket/linux/getpeername.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of getpeername.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/socket/getpeername.h"
+#include "hdr/types/socklen_t.h"
+#include "hdr/types/struct_sockaddr.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/getpeername.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, getpeername,
+                   (int sockfd, struct sockaddr *__restrict addr,
+                    socklen_t *__restrict addrlen)) {
+  auto result = linux_syscalls::getpeername(sockfd, addr, addrlen);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+
+  return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/socket/linux/getsockname.cpp b/libc/src/sys/socket/linux/getsockname.cpp
new file mode 100644
index 0000000000000..e5734b307bf71
--- /dev/null
+++ b/libc/src/sys/socket/linux/getsockname.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of getsockname.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/sys/socket/getsockname.h"
+#include "hdr/types/socklen_t.h"
+#include "hdr/types/struct_sockaddr.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/getsockname.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, getsockname,
+                   (int sockfd, struct sockaddr *__restrict addr,
+                    socklen_t *__restrict addrlen)) {
+  auto result = linux_syscalls::getsockname(sockfd, addr, addrlen);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+
+  return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt
index e29140ee06b24..5b10ed2e5df0e 100644
--- a/libc/test/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/test/src/sys/socket/linux/CMakeLists.txt
@@ -138,6 +138,32 @@ add_libc_unittest(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
+add_libc_unittest(
+  sockname_test
+  SUITE
+    libc_sys_socket_unittests
+  SRCS
+    sockname_test.cpp
+  DEPENDS
+    .socket_test_support
+    libc.include.sys_socket
+    libc.hdr.sys_socket_macros
+    libc.hdr.types.struct_sockaddr_un
+    libc.src.errno.errno
+    libc.src.sys.socket.accept
+    libc.src.sys.socket.bind
+    libc.src.sys.socket.connect
+    libc.src.sys.socket.getpeername
+    libc.src.sys.socket.getsockname
+    libc.src.sys.socket.listen
+    libc.src.sys.socket.socket
+    libc.src.stdio.remove
+    libc.src.unistd.close
+    libc.src.__support.CPP.scope
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
 add_libc_unittest(
   send_recv_test
   SUITE
diff --git a/libc/test/src/sys/socket/linux/sockname_test.cpp b/libc/test/src/sys/socket/linux/sockname_test.cpp
new file mode 100644
index 0000000000000..0ee7b5b75bbeb
--- /dev/null
+++ b/libc/test/src/sys/socket/linux/sockname_test.cpp
@@ -0,0 +1,156 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unittests for getsockname and getpeername.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/sys_socket_macros.h"
+#include "hdr/types/struct_sockaddr_un.h"
+#include "src/__support/CPP/scope.h"
+#include "src/stdio/remove.h"
+#include "src/sys/socket/accept.h"
+#include "src/sys/socket/bind.h"
+#include "src/sys/socket/connect.h"
+#include "src/sys/socket/getpeername.h"
+#include "src/sys/socket/getsockname.h"
+#include "src/sys/socket/listen.h"
+#include "src/sys/socket/socket.h"
+#include "src/unistd/close.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/src/sys/socket/linux/socket_test_support.h"
+
+using LIBC_NAMESPACE::testing::make_sockaddr_un;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+using LlvmLibcSockNameTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+using LIBC_NAMESPACE::cpp::scope_exit;
+
+TEST_F(LlvmLibcSockNameTest, GetSockNameAndPeerName) {
+  // 1. Invalid Socket
+  struct sockaddr_un addr;
+  socklen_t addr_len = sizeof(addr);
+  ASSERT_THAT(LIBC_NAMESPACE::getsockname(
+                  -1, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+              Fails(EBADF));
+  ASSERT_THAT(LIBC_NAMESPACE::getpeername(
+                  -1, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+              Fails(EBADF));
+
+  // 2. Unbound Socket
+  int sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_STREAM, 0);
+  ASSERT_GE(sock, 0);
+  ASSERT_ERRNO_SUCCESS();
+  scope_exit close_sock(
+      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(sock), Succeeds(0)); });
+
+  // getsockname on unbound socket should succeed
+  addr_len = sizeof(addr);
+  ASSERT_THAT(LIBC_NAMESPACE::getsockname(
+                  sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+              Succeeds(0));
+  ASSERT_GE(addr_len, static_cast<socklen_t>(sizeof(sa_family_t)));
+  ASSERT_EQ(addr.sun_family, static_cast<sa_family_t>(AF_UNIX));
+
+  // getpeername on unbound/unconnected socket should fail with ENOTCONN
+  addr_len = sizeof(addr);
+  ASSERT_THAT(LIBC_NAMESPACE::getpeername(
+                  sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+              Fails(ENOTCONN));
+
+  // 3. Connected Sockets
+  const char *client_file = "getsockname_client.test";
+  const auto client_path = libc_make_test_file_path(client_file);
+  struct sockaddr_un client_addr;
+  ASSERT_TRUE(make_sockaddr_un(client_path, client_addr));
+
+  const char *server_file = "getsockname_server.test";
+  const auto server_path = libc_make_test_file_path(server_file);
+  struct sockaddr_un server_addr;
+  ASSERT_TRUE(make_sockaddr_un(server_path, server_addr));
+
+  int server_sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_STREAM, 0);
+  ASSERT_GE(server_sock, 0);
+  ASSERT_ERRNO_SUCCESS();
+  scope_exit close_server_sock(
+      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(server_sock), Succeeds(0)); });
+
+  ASSERT_THAT(LIBC_NAMESPACE::bind(
+                  server_sock,
+                  reinterpret_cast<const struct sockaddr *>(&server_addr),
+                  sizeof(struct sockaddr_un)),
+              Succeeds(0));
+  scope_exit remove_server_path(
+      [&] { ASSERT_THAT(LIBC_NAMESPACE::remove(server_path), Succeeds(0)); });
+
+  ASSERT_THAT(LIBC_NAMESPACE::listen(server_sock, 1), Succeeds(0));
+
+  int client_sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_STREAM, 0);
+  ASSERT_GE(client_sock, 0);
+  ASSERT_ERRNO_SUCCESS();
+  scope_exit close_client_sock(
+      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(client_sock), Succeeds(0)); });
+
+  ASSERT_THAT(LIBC_NAMESPACE::bind(
+                  client_sock,
+                  reinterpret_cast<const struct sockaddr *>(&client_addr),
+                  sizeof(struct sockaddr_un)),
+              Succeeds(0));
+  scope_exit remove_client_path(
+      [&] { ASSERT_THAT(LIBC_NAMESPACE::remove(client_path), Succeeds(0)); });
+
+  ASSERT_THAT(LIBC_NAMESPACE::connect(
+                  client_sock,
+                  reinterpret_cast<const struct sockaddr *>(&server_addr),
+                  sizeof(struct sockaddr_un)),
+              Succeeds(0));
+
+  int accepted_sock = LIBC_NAMESPACE::accept(server_sock, nullptr, nullptr);
+  ASSERT_GE(accepted_sock, 0);
+  ASSERT_ERRNO_SUCCESS();
+  scope_exit close_accepted_sock(
+      [&] { ASSERT_THAT(LIBC_NAMESPACE::close(accepted_sock), Succeeds(0)); });
+
+  // Test getsockname on client_sock (should be client_path)
+  addr_len = sizeof(addr);
+  ASSERT_THAT(
+      LIBC_NAMESPACE::getsockname(
+          client_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+      Succeeds(0));
+  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
+              LIBC_NAMESPACE::testing::MatchesAddress(client_path));
+
+  // Test getpeername on client_sock (should be server_path)
+  addr_len = sizeof(addr);
+  ASSERT_THAT(
+      LIBC_NAMESPACE::getpeername(
+          client_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+      Succeeds(0));
+  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
+              LIBC_NAMESPACE::testing::MatchesAddress(server_path));
+
+  // Test getsockname on accepted_sock (should be server_path)
+  addr_len = sizeof(addr);
+  ASSERT_THAT(
+      LIBC_NAMESPACE::getsockname(
+          accepted_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+      Succeeds(0));
+  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
+              LIBC_NAMESPACE::testing::MatchesAddress(server_path));
+
+  // Test getpeername on accepted_sock (should be client_path)
+  addr_len = sizeof(addr);
+  ASSERT_THAT(
+      LIBC_NAMESPACE::getpeername(
+          accepted_sock, reinterpret_cast<struct sockaddr *>(&addr), &addr_len),
+      Succeeds(0));
+  ASSERT_THAT((LIBC_NAMESPACE::testing::SocketAddress{addr, addr_len}),
+              LIBC_NAMESPACE::testing::MatchesAddress(client_path));
+}



More information about the libc-commits mailing list