Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.execve
libc.src.unistd.faccessat
libc.src.unistd.fchdir
libc.src.unistd.fchown
libc.src.unistd.fpathconf
libc.src.unistd.fsync
libc.src.unistd.ftruncate
Expand Down
8 changes: 8 additions & 0 deletions libc/include/unistd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ functions:
return_type: int
arguments:
- type: int
- name: fchown
standards:
- POSIX
return_type: int
arguments:
- type: int
- type: uid_t
- type: gid_t
- name: fork
standards:
- POSIX
Expand Down
7 changes: 7 additions & 0 deletions libc/src/unistd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.fchdir
)

add_entrypoint_object(
fchown
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.fchown
)

add_entrypoint_object(
fork
ALIAS
Expand Down
22 changes: 22 additions & 0 deletions libc/src/unistd/fchown.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Implementation header for fchown ------------------------*- 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_UNISTD_FCHOWN_H_
#define LLVM_LIBC_SRC_UNISTD_FCHOWN_H_

#include "hdr/types/gid_t.h"
#include "hdr/types/uid_t.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

int fchown(int fildes, uid_t owner, gid_t group);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_UNISTD_FCHOWN_H_
14 changes: 14 additions & 0 deletions libc/src/unistd/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ add_entrypoint_object(
libc.src.errno.errno
)

add_entrypoint_object(
fchown
SRCS
fchown.cpp
HDRS
../fchown.h
DEPENDS
libc.hdr.types.uid_t
libc.hdr.types.gid_t
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)

add_entrypoint_object(
fork
SRCS
Expand Down
29 changes: 29 additions & 0 deletions libc/src/unistd/linux/fchown.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- Linux implementation of fchown ------------------------------------===//
//
// 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/unistd/fchown.h"

#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"

#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include <sys/syscall.h> // For syscall numbers.

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, fchown, (int fildes, uid_t owner, gid_t group)) {
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_fchown, fildes, owner, group);
if (ret < 0) {
libc_errno = -ret;
return -1;
}
return 0;
}

} // namespace LIBC_NAMESPACE_DECL
20 changes: 20 additions & 0 deletions libc/test/src/unistd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,26 @@ add_libc_unittest(
libc.test.UnitTest.ErrnoSetterMatcher
)

add_libc_unittest(
fchown_test
SUITE
libc_unistd_unittests
SRCS
fchown_test.cpp
DEPENDS
libc.hdr.fcntl_macros
libc.include.unistd
libc.src.errno.errno
libc.src.unistd.fchown
libc.src.unistd.close
libc.src.unistd.unlink
libc.src.fcntl.open
libc.src.unistd.getuid
libc.src.unistd.getgid
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)

add_libc_unittest(
ftruncate_test
SUITE
Expand Down
50 changes: 50 additions & 0 deletions libc/test/src/unistd/fchown_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===-- Unittests for fchown ----------------------------------------------===//
//
// 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/fcntl/open.h"
#include "src/unistd/close.h"
#include "src/unistd/fchown.h"
#include "src/unistd/getgid.h"
#include "src/unistd/getuid.h"
#include "src/unistd/unlink.h"

#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"

#include "hdr/fcntl_macros.h"
#include <sys/stat.h>

using LlvmLibcFchownTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;

TEST_F(LlvmLibcFchownTest, FchownSuccess) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
uid_t my_uid = LIBC_NAMESPACE::getuid();
gid_t my_gid = LIBC_NAMESPACE::getgid();
constexpr const char *FILENAME = "fchown.test";
auto TEST_FILE = libc_make_test_file_path(FILENAME);

// Create a test file.
int write_fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(write_fd, 0);

// Change the ownership of the file.
ASSERT_THAT(LIBC_NAMESPACE::fchown(write_fd, my_uid, my_gid), Succeeds(0));

// Close the file descriptor.
ASSERT_THAT(LIBC_NAMESPACE::close(write_fd), Succeeds(0));

// Clean up the test file.
ASSERT_THAT(LIBC_NAMESPACE::unlink(TEST_FILE), Succeeds(0));
}

TEST_F(LlvmLibcFchownTest, ChownInvalidFileDescriptor) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
ASSERT_THAT(LIBC_NAMESPACE::chown(-1, 1000, 1000), Fails(ENOENT));
}
Loading