[libc] add socket function

This patch adds the function "socket" from the header "sys/socket". It's
a simple syscall wrapper, and I plan on adding the related functions in
a followup patch.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D149622
This commit is contained in:
Michael Jones 2023-04-24 16:55:54 -07:00
parent fc19204918
commit ee17fd7d46
18 changed files with 213 additions and 14 deletions

View File

@ -203,6 +203,10 @@ def SysSelectAPI : PublicAPI<"sys/select.h"> {
"struct timeval"];
}
def SysSocketAPI : PublicAPI<"sys/socket.h"> {
let Types = ["struct sockaddr", "sa_family_t"];
}
def SysResourceAPI : PublicAPI<"sys/resource.h"> {
let Types = ["rlim_t", "struct rlimit"];
}

View File

@ -145,6 +145,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# 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

View File

@ -388,6 +388,8 @@ add_gen_header(
DEPENDS
.llvm_libc_common_h
.llvm-libc-macros.sys_socket_macros
.llvm-libc-types.struct_sockaddr
.llvm-libc-types.sa_family_t
)
add_gen_header(

View File

@ -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

View File

@ -87,3 +87,5 @@ add_header(struct_termios HDR struct_termios.h DEPENDS .cc_t .speed_t .tcflag_t)
add_header(__getoptargv_t HDR __getoptargv_t.h)
add_header(wchar_t HDR wchar_t.h)
add_header(wint_t HDR wint_t.h)
add_header(sa_family_t HDR sa_family_t.h)
add_header(struct_sockaddr HDR struct_sockaddr.h)

View File

@ -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__

View File

@ -0,0 +1,21 @@
//===-- 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 <llvm-libc-types/sa_family_t.h>
struct sockaddr {
sa_family_t sa_family;
// sa_data is a variable length array. It is provided with a length of one
// here as a placeholder.
char sa_data[1];
};
#endif // __LLVM_LIBC_TYPES_STRUCT_STAT_H__

View File

@ -110,19 +110,6 @@ def Linux : StandardSpec<"Linux"> {
]
>;
HeaderSpec SysSocket = HeaderSpec<
"sys/socket.h",
[
Macro<"AF_UNSPEC">,
Macro<"AF_LOCAL">,
Macro<"AF_INET">,
Macro<"AF_INET6">,
],
[], // Types
[], // Enumerations
[] // Functions
>;
HeaderSpec SysTime = HeaderSpec<
"sys/time.h",
[
@ -184,7 +171,6 @@ def Linux : StandardSpec<"Linux"> {
SysMMan,
SysPrctl,
SysRandom,
SysSocket,
SysTime,
Signal,
];

View File

@ -80,6 +80,10 @@ def RestrictedFdSetPtr : RestrictedPtrType<FdSet>;
def GetoptArgvT : NamedType<"__getoptargv_t">;
def StructSockAddr : NamedType<"struct sockaddr">;
def StructSockAddrPtr : PtrType<StructSockAddr>;
def SAFamilyType : NamedType<"sa_family_t">;
def POSIX : StandardSpec<"POSIX"> {
PtrType CharPtr = PtrType<CharType>;
RestrictedPtrType RestrictedCharPtr = RestrictedPtrType<CharType>;
@ -1347,6 +1351,34 @@ def POSIX : StandardSpec<"POSIX"> {
]
>;
HeaderSpec SysSocket = HeaderSpec<
"sys/socket.h",
[
Macro<"AF_UNSPEC">,
Macro<"AF_UNIX">,
Macro<"AF_LOCAL">,
Macro<"AF_INET">,
Macro<"AF_INET6">,
Macro<"SOCK_STREAM">,
Macro<"SOCK_DGRAM">,
Macro<"SOCK_RAW">,
Macro<"SOCK_RDM">,
Macro<"SOCK_SEQPACKET">,
Macro<"SOCK_PACKET">,
], // Macros
[
StructSockAddr, SAFamilyType,
], // Types
[], // Enumerations
[
FunctionSpec<
"socket",
RetValSpec<IntType>,
[ArgSpec<IntType>, ArgSpec<IntType>, ArgSpec<IntType>]
>,
] // Functions
>;
HeaderSpec SysTypes = HeaderSpec<
"sys/types.h",
[], // Macros
@ -1373,6 +1405,7 @@ def POSIX : StandardSpec<"POSIX"> {
SysMMan,
SysResource,
SysSelect,
SysSocket,
SysStat,
SysTypes,
SysUtsName,

View File

@ -2,6 +2,7 @@ add_subdirectory(mman)
add_subdirectory(random)
add_subdirectory(resource)
add_subdirectory(select)
add_subdirectory(socket)
add_subdirectory(sendfile)
add_subdirectory(stat)
add_subdirectory(utsname)

View File

@ -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
)

View File

@ -0,0 +1,12 @@
add_entrypoint_object(
socket
SRCS
socket.cpp
HDRS
../socket.h
DEPENDS
libc.include.sys_syscall
libc.include.sys_socket
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)

View File

@ -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 <linux/net.h> // For SYS_SOCKET socketcall number.
#include <sys/syscall.h> // 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

View File

@ -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

View File

@ -3,6 +3,7 @@ add_subdirectory(random)
add_subdirectory(resource)
add_subdirectory(select)
add_subdirectory(sendfile)
add_subdirectory(socket)
add_subdirectory(stat)
add_subdirectory(utsname)
add_subdirectory(wait)

View File

@ -0,0 +1,3 @@
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()

View File

@ -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
)

View File

@ -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 <sys/socket.h> // 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);
}