Skip to content

Commit 10be669

Browse files
authored
[libc] Implement getsockopt and setsockopt on linux (#192237)
This patch implements getsockopt and setsockopt socket functions on Linux. It follows the established pattern of wrapping socketcall or using direct syscalls. I added a basic test setting a couple of options. I only added the first couple of simple constants (e.g. whose value does not depend on the architecture). I've left the others for a separate patch.
1 parent 4097ec7 commit 10be669

16 files changed

Lines changed: 424 additions & 0 deletions

File tree

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,9 @@ if(LLVM_LIBC_FULL_BUILD)
12141214
libc.src.sys.socket.accept
12151215
libc.src.sys.socket.bind
12161216
libc.src.sys.socket.connect
1217+
libc.src.sys.socket.getsockopt
12171218
libc.src.sys.socket.listen
1219+
libc.src.sys.socket.setsockopt
12181220
libc.src.sys.socket.socket
12191221
)
12201222
endif()

libc/config/linux/riscv/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,9 @@ if(LLVM_LIBC_FULL_BUILD)
13481348
libc.src.sys.socket.accept
13491349
libc.src.sys.socket.bind
13501350
libc.src.sys.socket.connect
1351+
libc.src.sys.socket.getsockopt
13511352
libc.src.sys.socket.listen
1353+
libc.src.sys.socket.setsockopt
13521354
libc.src.sys.socket.socket
13531355
libc.src.sys.socket.socketpair
13541356
libc.src.sys.socket.send

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,8 +1419,10 @@ if(LLVM_LIBC_FULL_BUILD)
14191419
libc.src.sys.socket.socket
14201420
libc.src.sys.socket.bind
14211421
libc.src.sys.socket.connect
1422+
libc.src.sys.socket.getsockopt
14221423
libc.src.sys.socket.listen
14231424
libc.src.sys.socket.socketpair
1425+
libc.src.sys.socket.setsockopt
14241426
libc.src.sys.socket.send
14251427
libc.src.sys.socket.sendto
14261428
libc.src.sys.socket.sendmsg

libc/include/llvm-libc-macros/linux/sys-socket-macros.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,22 @@
2525
#define SOCK_SEQPACKET 5
2626
#define SOCK_PACKET 10
2727

28+
#define SOL_SOCKET 1
29+
30+
#define SO_DEBUG 1
31+
#define SO_REUSEADDR 2
32+
#define SO_TYPE 3
33+
#define SO_ERROR 4
34+
#define SO_DONTROUTE 5
35+
#define SO_BROADCAST 6
36+
#define SO_SNDBUF 7
37+
#define SO_RCVBUF 8
38+
#define SO_KEEPALIVE 9
39+
#define SO_OOBINLINE 10
40+
#define SO_NO_CHECK 11
41+
#define SO_PRIORITY 12
42+
#define SO_LINGER 13
43+
#define SO_BSDCOMPAT 14
44+
#define SO_REUSEPORT 15
45+
2846
#endif // LLVM_LIBC_MACROS_LINUX_SYS_SOCKET_MACROS_H

libc/include/sys/socket.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ functions:
3939
- type: int
4040
- type: const struct sockaddr *
4141
- type: socklen_t
42+
- name: getsockopt
43+
standards:
44+
- POSIX
45+
return_type: int
46+
arguments:
47+
- type: int
48+
- type: int
49+
- type: int
50+
- type: void *__restrict
51+
- type: socklen_t *__restrict
4252
- name: listen
4353
standards:
4454
- POSIX
@@ -102,6 +112,16 @@ functions:
102112
- type: int
103113
- type: const struct sockaddr *
104114
- type: socklen_t
115+
- name: setsockopt
116+
standards:
117+
- POSIX
118+
return_type: int
119+
arguments:
120+
- type: int
121+
- type: int
122+
- type: int
123+
- type: const void *
124+
- type: socklen_t
105125
- name: socket
106126
standards:
107127
- POSIX

libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ add_header_library(
5353
libc.include.sys_syscall
5454
)
5555

56+
add_header_library(
57+
getsockopt
58+
HDRS
59+
getsockopt.h
60+
DEPENDS
61+
libc.src.__support.common
62+
libc.src.__support.error_or
63+
libc.src.__support.libc_errno
64+
libc.src.__support.macros.config
65+
libc.hdr.types.socklen_t
66+
libc.include.sys_syscall
67+
)
68+
5669
add_header_library(
5770
listen
5871
HDRS
@@ -78,6 +91,19 @@ add_header_library(
7891
libc.include.sys_syscall
7992
)
8093

94+
add_header_library(
95+
setsockopt
96+
HDRS
97+
setsockopt.h
98+
DEPENDS
99+
libc.src.__support.common
100+
libc.src.__support.error_or
101+
libc.src.__support.libc_errno
102+
libc.src.__support.macros.config
103+
libc.hdr.types.socklen_t
104+
libc.include.sys_syscall
105+
)
106+
81107
add_header_library(
82108
raise
83109
HDRS
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===-- Implementation header for getsockopt --------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETSOCKOPT_H
10+
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETSOCKOPT_H
11+
12+
#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
13+
#include "src/__support/common.h"
14+
#include "src/__support/error_or.h"
15+
#include "src/__support/macros/config.h"
16+
17+
#include "hdr/types/socklen_t.h"
18+
#include <linux/net.h> // For SYS_GETSOCKOPT socketcall number.
19+
#include <sys/syscall.h> // For syscall numbers
20+
21+
namespace LIBC_NAMESPACE_DECL {
22+
namespace linux_syscalls {
23+
24+
LIBC_INLINE ErrorOr<int> getsockopt(int sockfd, int level, int optname,
25+
void *optval, socklen_t *optlen) {
26+
#ifdef SYS_getsockopt
27+
int ret =
28+
syscall_impl<int>(SYS_getsockopt, sockfd, level, optname, optval, optlen);
29+
#elif defined(SYS_socketcall)
30+
unsigned long sockcall_args[5] = {static_cast<unsigned long>(sockfd),
31+
static_cast<unsigned long>(level),
32+
static_cast<unsigned long>(optname),
33+
reinterpret_cast<unsigned long>(optval),
34+
reinterpret_cast<unsigned long>(optlen)};
35+
int ret = syscall_impl<int>(SYS_socketcall, SYS_GETSOCKOPT, sockcall_args);
36+
#else
37+
#error "getsockopt and socketcall syscalls unavailable for this platform."
38+
#endif
39+
40+
if (ret < 0)
41+
return Error(-static_cast<int>(ret));
42+
return ret;
43+
}
44+
45+
} // namespace linux_syscalls
46+
} // namespace LIBC_NAMESPACE_DECL
47+
48+
#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETSOCKOPT_H
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===-- Implementation header for setsockopt --------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETSOCKOPT_H
10+
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETSOCKOPT_H
11+
12+
#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
13+
#include "src/__support/common.h"
14+
#include "src/__support/error_or.h"
15+
#include "src/__support/macros/config.h"
16+
17+
#include "hdr/types/socklen_t.h"
18+
#include <linux/net.h> // For SYS_SETSOCKOPT socketcall number.
19+
#include <sys/syscall.h> // For syscall numbers
20+
21+
namespace LIBC_NAMESPACE_DECL {
22+
namespace linux_syscalls {
23+
24+
LIBC_INLINE ErrorOr<int> setsockopt(int sockfd, int level, int optname,
25+
const void *optval, socklen_t optlen) {
26+
#ifdef SYS_setsockopt
27+
int ret =
28+
syscall_impl<int>(SYS_setsockopt, sockfd, level, optname, optval, optlen);
29+
#elif defined(SYS_socketcall)
30+
unsigned long sockcall_args[5] = {static_cast<unsigned long>(sockfd),
31+
static_cast<unsigned long>(level),
32+
static_cast<unsigned long>(optname),
33+
reinterpret_cast<unsigned long>(optval),
34+
static_cast<unsigned long>(optlen)};
35+
int ret = syscall_impl<int>(SYS_socketcall, SYS_SETSOCKOPT, sockcall_args);
36+
#else
37+
#error "setsockopt and socketcall syscalls unavailable for this platform."
38+
#endif
39+
40+
if (ret < 0)
41+
return Error(-static_cast<int>(ret));
42+
return ret;
43+
}
44+
45+
} // namespace linux_syscalls
46+
} // namespace LIBC_NAMESPACE_DECL
47+
48+
#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETSOCKOPT_H

libc/src/sys/socket/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ add_entrypoint_object(
3030
.${LIBC_TARGET_OS}.connect
3131
)
3232

33+
add_entrypoint_object(
34+
getsockopt
35+
ALIAS
36+
DEPENDS
37+
.${LIBC_TARGET_OS}.getsockopt
38+
)
39+
3340
add_entrypoint_object(
3441
listen
3542
ALIAS
@@ -58,6 +65,13 @@ add_entrypoint_object(
5865
.${LIBC_TARGET_OS}.sendto
5966
)
6067

68+
add_entrypoint_object(
69+
setsockopt
70+
ALIAS
71+
DEPENDS
72+
.${LIBC_TARGET_OS}.setsockopt
73+
)
74+
6175
add_entrypoint_object(
6276
sendmsg
6377
ALIAS

libc/src/sys/socket/getsockopt.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header for getsockopt --------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SYS_SOCKET_GETSOCKOPT_H
10+
#define LLVM_LIBC_SRC_SYS_SOCKET_GETSOCKOPT_H
11+
12+
#include "src/__support/macros/config.h"
13+
14+
#include "hdr/types/socklen_t.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
int getsockopt(int sockfd, int level, int optname, void *__restrict optval,
19+
socklen_t *__restrict optlen);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_SYS_SOCKET_GETSOCKOPT_H

0 commit comments

Comments
 (0)