Skip to content

Commit c44b475

Browse files
committed
Implement gethostname
Matching the behavior of glibc version 2.2 and later. If the size of the array name is not large enough, then anything might happen. In this case, what happens to the array name will be determined by the implementation of LIBC_NAMESPACE_DECL::strncpy Signed-off-by: ZakyHermawan <[email protected]>
1 parent 6e7da07 commit c44b475

File tree

10 files changed

+156
-0
lines changed

10 files changed

+156
-0
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ set(TARGET_LIBC_ENTRYPOINTS
327327
libc.src.unistd.getcwd
328328
libc.src.unistd.getentropy
329329
libc.src.unistd.geteuid
330+
libc.src.unistd.gethostname
330331
libc.src.unistd.getpid
331332
libc.src.unistd.getppid
332333
libc.src.unistd.getsid

libc/config/linux/riscv/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ set(TARGET_LIBC_ENTRYPOINTS
324324
libc.src.unistd.ftruncate
325325
libc.src.unistd.getcwd
326326
libc.src.unistd.geteuid
327+
libc.src.unistd.gethostname
327328
libc.src.unistd.getpid
328329
libc.src.unistd.getppid
329330
libc.src.unistd.getsid

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ set(TARGET_LIBC_ENTRYPOINTS
326326
libc.src.unistd.getcwd
327327
libc.src.unistd.getentropy
328328
libc.src.unistd.geteuid
329+
libc.src.unistd.gethostname
329330
libc.src.unistd.getpid
330331
libc.src.unistd.getppid
331332
libc.src.unistd.getsid

libc/include/unistd.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ functions:
141141
return_type: uid_t
142142
arguments:
143143
- type: void
144+
- name: gethostname
145+
standards:
146+
- POSIX
147+
return_type: int
148+
arguments:
149+
- type: char *
150+
- type: size_t
144151
- name: getopt
145152
standards:
146153
- POSIX

libc/src/unistd/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ add_entrypoint_object(
111111
.${LIBC_TARGET_OS}.getcwd
112112
)
113113

114+
add_entrypoint_object(
115+
gethostname
116+
ALIAS
117+
DEPENDS
118+
.${LIBC_TARGET_OS}.gethostname
119+
)
120+
114121
add_entrypoint_object(
115122
getpid
116123
ALIAS

libc/src/unistd/gethostname.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Implementation header for gethostname -------------------*- 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_UNISTD_GETHOSTNAME_H
10+
#define LLVM_LIBC_SRC_UNISTD_GETHOSTNAME_H
11+
12+
#include "hdr/types/size_t.h"
13+
#include "hdr/unistd_macros.h"
14+
#include "src/__support/macros/config.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
int gethostname(char *name, size_t len);
19+
20+
} // namespace LIBC_NAMESPACE_DECL
21+
22+
#endif // LLVM_LIBC_SRC_UNISTD_GETHOSTNAME_H

libc/src/unistd/linux/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,22 @@ add_entrypoint_object(
193193
libc.src.errno.errno
194194
)
195195

196+
add_entrypoint_object(
197+
gethostname
198+
SRCS
199+
gethostname.cpp
200+
HDRS
201+
../gethostname.h
202+
DEPENDS
203+
libc.hdr.types.size_t
204+
libc.include.sys_syscall
205+
libc.include.sys_utsname
206+
libc.src.__support.OSUtil.osutil
207+
libc.src.errno.errno
208+
libc.src.string.strlen
209+
libc.src.string.strncpy
210+
)
211+
196212
add_entrypoint_object(
197213
geteuid
198214
SRCS
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===-- Linux implementation of gethostname -------------------------------===//
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/unistd/gethostname.h"
10+
11+
#include "hdr/types/size_t.h"
12+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
13+
#include "src/__support/common.h"
14+
#include "src/__support/macros/config.h"
15+
16+
#include "src/string/strlen.h"
17+
#include "src/string/strncpy.h"
18+
#include "src/errno/libc_errno.h"
19+
20+
#include <sys/syscall.h> // For syscall numbers.
21+
#include <sys/utsname.h>
22+
23+
namespace LIBC_NAMESPACE_DECL {
24+
25+
// Matching the behavior of glibc version 2.2 and later.
26+
// Copies up to len bytes from the returned nodename field into name.
27+
LLVM_LIBC_FUNCTION(int, gethostname, (char *name, size_t len)) {
28+
29+
// Check for invalid pointer
30+
if (name == nullptr) {
31+
libc_errno = EFAULT;
32+
return -1;
33+
}
34+
35+
struct utsname unameData;
36+
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_uname, &unameData);
37+
38+
// Checks if the length of the nodename was greater than or equal to len, and if it is,
39+
// then the function returns -1 with errno set to ENAMETOOLONG.
40+
// In this case, a terminating null byte is not included in the returned name.
41+
if (strlen(unameData.nodename) >= len)
42+
{
43+
strncpy(name, unameData.nodename, len);
44+
libc_errno = ENAMETOOLONG;
45+
return -1;
46+
}
47+
48+
// If the size of the array name is not large enough (less than the size of nodename with null termination), then anything might happen.
49+
// In this case, what happens to the array name will be determined by the implementation of LIBC_NAMESPACE_DECL::strncpy
50+
strncpy(name, unameData.nodename, len);
51+
52+
if (ret < 0) {
53+
libc_errno = static_cast<int>(-ret);
54+
return -1;
55+
}
56+
57+
return 0;
58+
}
59+
60+
} // namespace LIBC_NAMESPACE_DECL
61+
62+

libc/test/src/unistd/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,17 @@ add_libc_unittest(
374374
libc.src.unistd.unlinkat
375375
)
376376

377+
add_libc_unittest(
378+
gethostname_test
379+
SUITE
380+
libc_unistd_unittests
381+
SRCS
382+
gethostname_test.cpp
383+
DEPENDS
384+
libc.src.unistd.gethostname
385+
libc.src.errno.errno
386+
)
387+
377388
add_libc_unittest(
378389
getpid_test
379390
SUITE
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===-- Unittests for gethostname -----------------------------------------===//
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/errno/libc_errno.h"
10+
#include "src/unistd/gethostname.h"
11+
#include "test/UnitTest/Test.h"
12+
13+
TEST(LlvmLibcGetHostNameTest, GetCurrHostName) {
14+
char hostbuffer[1024];
15+
int ret = LIBC_NAMESPACE::gethostname(hostbuffer, sizeof(hostbuffer));
16+
ASSERT_NE(ret, -1);
17+
ASSERT_ERRNO_SUCCESS();
18+
19+
ret = LIBC_NAMESPACE::gethostname(hostbuffer, 0);
20+
ASSERT_EQ(ret, -1);
21+
ASSERT_ERRNO_EQ(ENAMETOOLONG);
22+
23+
// test for invalid pointer
24+
char* nptr = nullptr;
25+
ret = LIBC_NAMESPACE::gethostname(nptr, 1);
26+
ASSERT_EQ(ret, -1);
27+
ASSERT_ERRNO_EQ(EFAULT);
28+
}

0 commit comments

Comments
 (0)