diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -145,6 +145,9 @@ # sys/sendfile entrypoints libc.src.sys.sendfile.sendfile + # sys/socket.h entrypoints + libc.src.sys.socket.socket + # sys/stat.h entrypoints libc.src.sys.stat.chmod libc.src.sys.stat.fchmod diff --git a/libc/include/llvm-libc-macros/linux/sys-socket-macros.h b/libc/include/llvm-libc-macros/linux/sys-socket-macros.h --- a/libc/include/llvm-libc-macros/linux/sys-socket-macros.h +++ b/libc/include/llvm-libc-macros/linux/sys-socket-macros.h @@ -18,4 +18,11 @@ #define AF_INET 2 // Internet IPv4 Protocol #define AF_INET6 10 // IP version 6 +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 +#define SOCK_RDM 4 +#define SOCK_SEQPACKET 5 +#define SOCK_PACKET 10 + #endif // __LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H diff --git a/libc/include/llvm-libc-types/sa_family_t.h b/libc/include/llvm-libc-types/sa_family_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/sa_family_t.h @@ -0,0 +1,19 @@ +//===-- Definition of sa_family_t type ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_TYPES_SA_FAMILY_T_H__ +#define __LLVM_LIBC_TYPES_SA_FAMILY_T_H__ + +// The posix standard only says of sa_family_t that it must be unsigned. The +// linux man page for "address_families" lists approximately 32 different +// address families, meaning that a short 16 bit number will have plenty of +// space for all of them. + +typedef unsigned short sa_family_t; + +#endif // __LLVM_LIBC_TYPES_SA_FAMILY_T_H__ diff --git a/libc/include/llvm-libc-types/struct_sockaddr.h b/libc/include/llvm-libc-types/struct_sockaddr.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/struct_sockaddr.h @@ -0,0 +1,19 @@ +//===-- Definition of struct stat -----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_TYPES_STRUCT_STAT_H__ +#define __LLVM_LIBC_TYPES_STRUCT_STAT_H__ + +#include + +struct sockaddr { + sa_family_t sa_family; + char sa_data[14]; +} + +#endif // __LLVM_LIBC_TYPES_STRUCT_STAT_H__ diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt --- a/libc/src/sys/CMakeLists.txt +++ b/libc/src/sys/CMakeLists.txt @@ -2,6 +2,7 @@ add_subdirectory(random) add_subdirectory(resource) add_subdirectory(select) +add_subdirectory(socket) add_subdirectory(sendfile) add_subdirectory(stat) add_subdirectory(utsname) diff --git a/libc/src/sys/socket/CMakeLists.txt b/libc/src/sys/socket/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/sys/socket/CMakeLists.txt @@ -0,0 +1,11 @@ +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) +endif() + +add_entrypoint_object( + socket + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.socket +) + diff --git a/libc/src/sys/socket/linux/CMakeLists.txt b/libc/src/sys/socket/linux/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/sys/socket/linux/CMakeLists.txt @@ -0,0 +1,11 @@ +add_entrypoint_object( + socket + SRCS + socket.cpp + HDRS + ../socket.h + DEPENDS + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) diff --git a/libc/src/sys/socket/linux/socket.cpp b/libc/src/sys/socket/linux/socket.cpp new file mode 100644 --- /dev/null +++ b/libc/src/sys/socket/linux/socket.cpp @@ -0,0 +1,38 @@ +//===-- Linux implementation of socket ------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/sys/socket/socket.h" + +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" + +#include "src/errno/libc_errno.h" + +#include // For socketcall numbers. +#include // For syscall numbers. + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, socket, (int domain, int type, int protocol)) { +#ifdef SYS_socket + long ret = __llvm_libc::syscall_impl(SYS_socket, domain, type, protocol); +#elif defined(SYS_socketcall) + unsigned long sockcall_args[3] = {domain, type, protocol}; + long ret = + __llvm_libc::syscall_impl(SYS_socketcall, SYS_SOCKET, sockcall_args); +#else +#error "socket and socketcall syscalls unavailable for this platform." +#endif + if (ret < 0) { + libc_errno = -ret; + return -1; + } + return ret; +} + +} // namespace __llvm_libc diff --git a/libc/src/sys/socket/socket.h b/libc/src/sys/socket/socket.h new file mode 100644 --- /dev/null +++ b/libc/src/sys/socket/socket.h @@ -0,0 +1,18 @@ +//===-- Implementation header for socket ------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SYS_SOCKET_SENDFILE_H +#define LLVM_LIBC_SRC_SYS_SOCKET_SENDFILE_H + +namespace __llvm_libc { + +int socket(int domain, int type, int protocol); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SYS_SOCKET_SENDFILE_H diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt --- a/libc/test/src/sys/CMakeLists.txt +++ b/libc/test/src/sys/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(resource) add_subdirectory(select) add_subdirectory(sendfile) +add_subdirectory(socket) add_subdirectory(stat) add_subdirectory(utsname) add_subdirectory(wait) diff --git a/libc/test/src/sys/socket/CMakeLists.txt b/libc/test/src/sys/socket/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/test/src/sys/socket/CMakeLists.txt @@ -0,0 +1,3 @@ +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) + add_subdirectory(${LIBC_TARGET_OS}) +endif() diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/test/src/sys/socket/linux/CMakeLists.txt @@ -0,0 +1,14 @@ +add_custom_target(libc_sys_socket_unittests) + +add_libc_unittest( + socket_test + SUITE + libc_sys_socket_unittests + SRCS + socket_test.cpp + DEPENDS + libc.include.sys_socket + libc.src.errno.errno + libc.src.sys.socket.socket + libc.src.unistd.close +) diff --git a/libc/test/src/sys/socket/linux/socket_test.cpp b/libc/test/src/sys/socket/linux/socket_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/sys/socket/linux/socket_test.cpp @@ -0,0 +1,24 @@ +//===-- Unittests for socket ----------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/sys/socket/socket.h" + +#include "src/unistd/close.h" + +#include "src/errno/libc_errno.h" +#include "test/UnitTest/Test.h" + +#include // For AF_LOCAL and SOCK_DGRAM + +TEST(LlvmLibcSocketTest, LocalSocket) { + int sock = __llvm_libc::socket(AF_LOCAL, SOCK_DGRAM, 0); + ASSERT_GE(sock, 0); + ASSERT_EQ(libc_errno, 0); + + __llvm_libc::close(sock); +}