Skip to content

Commit 13dd2fd

Browse files
[libc] Put bind back, fix gcc build (#109341)
Fixes #106467. Bind was accidentally removed while trying to clean up functions that didn't end up being needed. The GCC issue was just a warning treated as an error.
1 parent 36293ee commit 13dd2fd

File tree

8 files changed

+157
-1
lines changed

8 files changed

+157
-1
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,7 @@ if(LLVM_LIBC_FULL_BUILD)
10421042

10431043
# sys/socket.h entrypoints
10441044
libc.src.sys.socket.socket
1045+
libc.src.sys.socket.bind
10451046
libc.src.sys.socket.socketpair
10461047
libc.src.sys.socket.send
10471048
libc.src.sys.socket.sendto

libc/include/llvm-libc-types/struct_sockaddr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct sockaddr {
1515
sa_family_t sa_family;
1616
// sa_data is a variable length array. It is provided with a length of one
1717
// here as a placeholder.
18-
char sa_data[];
18+
char sa_data[1];
1919
};
2020

2121
#endif // LLVM_LIBC_TYPES_STRUCT_SOCKADDR_H

libc/src/sys/socket/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ add_entrypoint_object(
99
.${LIBC_TARGET_OS}.socket
1010
)
1111

12+
add_entrypoint_object(
13+
bind
14+
ALIAS
15+
DEPENDS
16+
.${LIBC_TARGET_OS}.bind
17+
)
18+
1219
add_entrypoint_object(
1320
socketpair
1421
ALIAS

libc/src/sys/socket/bind.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Implementation header for bind --------------------------*- 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_BIND_H
10+
#define LLVM_LIBC_SRC_SYS_SOCKET_BIND_H
11+
12+
#include "hdr/types/socklen_t.h"
13+
#include "hdr/types/struct_sockaddr.h"
14+
#include "src/__support/macros/config.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
19+
20+
} // namespace LIBC_NAMESPACE_DECL
21+
22+
#endif // LLVM_LIBC_SRC_SYS_SOCKET_BIND_H

libc/src/sys/socket/linux/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ add_entrypoint_object(
1111
libc.src.errno.errno
1212
)
1313

14+
add_entrypoint_object(
15+
bind
16+
SRCS
17+
bind.cpp
18+
HDRS
19+
../bind.h
20+
DEPENDS
21+
libc.include.sys_syscall
22+
libc.include.sys_socket
23+
libc.src.__support.OSUtil.osutil
24+
libc.src.errno.errno
25+
)
26+
1427
add_entrypoint_object(
1528
socketpair
1629
SRCS

libc/src/sys/socket/linux/bind.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===-- Linux implementation of bind --------------------------------------===//
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+
#include "src/sys/socket/bind.h"
10+
11+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12+
#include "src/__support/common.h"
13+
14+
#include "src/__support/macros/config.h"
15+
#include "src/errno/libc_errno.h"
16+
17+
#include <linux/net.h> // For SYS_SOCKET socketcall number.
18+
#include <sys/syscall.h> // For syscall numbers.
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
LLVM_LIBC_FUNCTION(int, bind,
23+
(int socket, const struct sockaddr *address,
24+
socklen_t address_len)) {
25+
#ifdef SYS_bind
26+
int ret =
27+
LIBC_NAMESPACE::syscall_impl<int>(SYS_bind, socket, address, address_len);
28+
#elif defined(SYS_socketcall)
29+
unsigned long sockcall_args[3] = {static_cast<unsigned long>(socket),
30+
reinterpret_cast<unsigned long>(address),
31+
static_cast<unsigned long>(address_len)};
32+
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_BIND,
33+
sockcall_args);
34+
#else
35+
#error "socket and socketcall syscalls unavailable for this platform."
36+
#endif
37+
if (ret < 0) {
38+
libc_errno = -ret;
39+
return -1;
40+
}
41+
return ret;
42+
}
43+
44+
} // namespace LIBC_NAMESPACE_DECL

libc/test/src/sys/socket/linux/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@ add_libc_unittest(
1313
libc.src.unistd.close
1414
)
1515

16+
add_libc_unittest(
17+
bind_test
18+
SUITE
19+
libc_sys_socket_unittests
20+
SRCS
21+
bind_test.cpp
22+
DEPENDS
23+
libc.include.sys_socket
24+
libc.src.errno.errno
25+
libc.src.sys.socket.socket
26+
libc.src.sys.socket.bind
27+
libc.src.stdio.remove
28+
libc.src.unistd.close
29+
)
30+
1631
add_libc_unittest(
1732
socketpair_test
1833
SUITE
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===-- Unittests for bind ------------------------------------------------===//
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+
#include "src/sys/socket/bind.h"
10+
#include "src/sys/socket/socket.h"
11+
12+
#include "src/stdio/remove.h"
13+
#include "src/unistd/close.h"
14+
15+
#include "src/errno/libc_errno.h"
16+
#include "test/UnitTest/Test.h"
17+
18+
#include <sys/socket.h> // For AF_UNIX and SOCK_DGRAM
19+
20+
TEST(LlvmLibcSocketTest, BindLocalSocket) {
21+
22+
const char *FILENAME = "bind_file.test";
23+
auto SOCK_PATH = libc_make_test_file_path(FILENAME);
24+
25+
int sock = LIBC_NAMESPACE::socket(AF_UNIX, SOCK_DGRAM, 0);
26+
ASSERT_GE(sock, 0);
27+
ASSERT_ERRNO_SUCCESS();
28+
29+
struct sockaddr_un my_addr;
30+
31+
my_addr.sun_family = AF_UNIX;
32+
unsigned int i = 0;
33+
for (;
34+
SOCK_PATH[i] != '\0' && (i < sizeof(sockaddr_un) - sizeof(sa_family_t));
35+
++i)
36+
my_addr.sun_path[i] = SOCK_PATH[i];
37+
my_addr.sun_path[i] = '\0';
38+
39+
// It's important that the path fits in the struct, if it doesn't then we
40+
// can't try to bind to the file.
41+
ASSERT_LT(
42+
i, static_cast<unsigned int>(sizeof(sockaddr_un) - sizeof(sa_family_t)));
43+
44+
int result =
45+
LIBC_NAMESPACE::bind(sock, reinterpret_cast<struct sockaddr *>(&my_addr),
46+
sizeof(struct sockaddr_un));
47+
48+
ASSERT_EQ(result, 0);
49+
ASSERT_ERRNO_SUCCESS();
50+
51+
LIBC_NAMESPACE::close(sock);
52+
53+
LIBC_NAMESPACE::remove(SOCK_PATH);
54+
}

0 commit comments

Comments
 (0)