Skip to content

Commit a535a9d

Browse files
committed
Move implementation of fcntl to OSUtil dir & resolve comments
1 parent 9dd1429 commit a535a9d

File tree

8 files changed

+144
-97
lines changed

8 files changed

+144
-97
lines changed

libc/src/__support/OSUtil/fcntl.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===-- Implementation header of internal fcntl function ---------------*- C++
2+
//-*-===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_FCNTL_H
11+
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_FCNTL_H
12+
13+
namespace LIBC_NAMESPACE::internal {
14+
15+
int fcntl(int fd, int cmd, void *arg = nullptr);
16+
17+
} // namespace LIBC_NAMESPACE::internal
18+
19+
#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_FCNTL_H

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@ add_object_library(
88
linux_util
99
SRCS
1010
exit.cpp
11+
fcntl.cpp
1112
HDRS
1213
io.h
1314
syscall.h
1415
DEPENDS
1516
.${LIBC_TARGET_ARCHITECTURE}.linux_${LIBC_TARGET_ARCHITECTURE}_util
1617
libc.src.__support.common
1718
libc.src.__support.CPP.string_view
19+
libc.src.errno.errno
20+
libc.hdr.fcntl_macros
21+
libc.hdr.types.struct_flock
22+
libc.hdr.types.struct_flock64
23+
libc.hdr.types.struct_f_owner_ex
1824
)
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//===-- Implementation of internal fcntl ----------------------------------===//
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/__support/OSUtil/fcntl.h"
10+
11+
#include "hdr/fcntl_macros.h"
12+
#include "hdr/types/struct_f_owner_ex.h"
13+
#include "hdr/types/struct_flock.h"
14+
#include "hdr/types/struct_flock64.h"
15+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
16+
#include "src/__support/common.h"
17+
#include "src/errno/libc_errno.h"
18+
19+
#include <stdarg.h>
20+
#include <sys/syscall.h> // For syscall numbers.
21+
22+
namespace LIBC_NAMESPACE::internal {
23+
24+
int fcntl(int fd, int cmd, void *arg) {
25+
switch (cmd) {
26+
case F_OFD_SETLKW: {
27+
struct flock *flk = reinterpret_cast<struct flock *>(arg);
28+
// convert the struct to a flock64
29+
struct flock64 flk64;
30+
flk64.l_type = flk->l_type;
31+
flk64.l_whence = flk->l_whence;
32+
flk64.l_start = flk->l_start;
33+
flk64.l_len = flk->l_len;
34+
flk64.l_pid = flk->l_pid;
35+
// create a syscall
36+
return LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64);
37+
}
38+
case F_OFD_GETLK:
39+
case F_OFD_SETLK: {
40+
struct flock *flk = reinterpret_cast<struct flock *>(arg);
41+
// convert the struct to a flock64
42+
struct flock64 flk64;
43+
flk64.l_type = flk->l_type;
44+
flk64.l_whence = flk->l_whence;
45+
flk64.l_start = flk->l_start;
46+
flk64.l_len = flk->l_len;
47+
flk64.l_pid = flk->l_pid;
48+
// create a syscall
49+
int retVal = LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64);
50+
// On failure, return
51+
if (retVal == -1)
52+
return -1;
53+
// Check for overflow, i.e. the offsets are not the same when cast
54+
// to off_t from off64_t.
55+
if (static_cast<off_t>(flk64.l_len) != flk64.l_len ||
56+
static_cast<off_t>(flk64.l_start) != flk64.l_start) {
57+
libc_errno = EOVERFLOW;
58+
return -1;
59+
}
60+
// Now copy back into flk, in case flk64 got modified
61+
flk->l_type = flk64.l_type;
62+
flk->l_whence = flk64.l_whence;
63+
flk->l_start = flk64.l_start;
64+
flk->l_len = flk64.l_len;
65+
flk->l_pid = flk64.l_pid;
66+
return retVal;
67+
}
68+
case F_GETOWN: {
69+
struct f_owner_ex fex;
70+
int retVal =
71+
LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, F_GETOWN_EX, &fex);
72+
if (retVal == -EINVAL)
73+
return LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, cmd,
74+
reinterpret_cast<void *>(arg));
75+
if (static_cast<unsigned long>(retVal) <= -4096UL)
76+
return fex.type == F_OWNER_PGRP ? -fex.pid : fex.pid;
77+
78+
libc_errno = -retVal;
79+
return -1;
80+
}
81+
// The general case
82+
default: {
83+
int retVal = LIBC_NAMESPACE::syscall_impl<int>(
84+
SYS_fcntl, fd, cmd, reinterpret_cast<void *>(arg));
85+
if (retVal >= 0) {
86+
return retVal;
87+
}
88+
libc_errno = -retVal;
89+
return -1;
90+
}
91+
}
92+
}
93+
94+
} // namespace LIBC_NAMESPACE::internal

libc/src/fcntl/linux/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,7 @@ add_entrypoint_object(
1818
../fcntl.h
1919
DEPENDS
2020
libc.include.fcntl
21-
libc.hdr.types.struct_flock
22-
libc.hdr.types.struct_flock64
23-
libc.hdr.types.struct_f_owner_ex
24-
libc.hdr.fcntl_macros
2521
libc.src.__support.OSUtil.osutil
26-
libc.src.errno.errno
2722
)
2823

2924
add_entrypoint_object(

libc/src/fcntl/linux/fcntl.cpp

Lines changed: 4 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -8,91 +8,20 @@
88

99
#include "src/fcntl/fcntl.h"
1010

11-
#include "hdr/fcntl_macros.h"
12-
#include "hdr/types/struct_f_owner_ex.h"
13-
#include "hdr/types/struct_flock.h"
14-
#include "hdr/types/struct_flock64.h"
15-
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
11+
#include "src/__support/OSUtil/fcntl.h"
1612
#include "src/__support/common.h"
17-
#include "src/errno/libc_errno.h"
1813

1914
#include <stdarg.h>
20-
#include <sys/syscall.h> // For syscall numbers.
2115

22-
// The OFD file locks require special handling for LARGEFILES
2316
namespace LIBC_NAMESPACE {
17+
2418
LLVM_LIBC_FUNCTION(int, fcntl, (int fd, int cmd, ...)) {
2519
void *arg;
2620
va_list varargs;
2721
va_start(varargs, cmd);
2822
arg = va_arg(varargs, void *);
2923
va_end(varargs);
30-
31-
switch (cmd) {
32-
case F_OFD_SETLKW: {
33-
struct flock *flk = reinterpret_cast<struct flock *>(arg);
34-
// convert the struct to a flock64
35-
struct flock64 flk64;
36-
flk64.l_type = flk->l_type;
37-
flk64.l_whence = flk->l_whence;
38-
flk64.l_start = flk->l_start;
39-
flk64.l_len = flk->l_len;
40-
flk64.l_pid = flk->l_pid;
41-
// create a syscall
42-
return syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64);
43-
}
44-
case F_OFD_GETLK:
45-
case F_OFD_SETLK: {
46-
struct flock *flk = reinterpret_cast<struct flock *>(arg);
47-
// convert the struct to a flock64
48-
struct flock64 flk64;
49-
flk64.l_type = flk->l_type;
50-
flk64.l_whence = flk->l_whence;
51-
flk64.l_start = flk->l_start;
52-
flk64.l_len = flk->l_len;
53-
flk64.l_pid = flk->l_pid;
54-
// create a syscall
55-
int retVal = syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64);
56-
// On failure, return
57-
if (retVal == -1)
58-
return -1;
59-
// Check for overflow, i.e. the offsets are not the same when cast
60-
// to off_t from off64_t.
61-
if (static_cast<off_t>(flk64.l_len) != flk64.l_len ||
62-
static_cast<off_t>(flk64.l_start) != flk64.l_start) {
63-
libc_errno = EOVERFLOW;
64-
return -1;
65-
}
66-
// Now copy back into flk, in case flk64 got modified
67-
flk->l_type = flk64.l_type;
68-
flk->l_whence = flk64.l_whence;
69-
flk->l_start = flk64.l_start;
70-
flk->l_len = flk64.l_len;
71-
flk->l_pid = flk64.l_pid;
72-
return retVal;
73-
}
74-
case F_GETOWN: {
75-
struct f_owner_ex fex;
76-
int retVal = syscall_impl<int>(SYS_fcntl, fd, F_GETOWN_EX, &fex);
77-
if (retVal == -EINVAL)
78-
return syscall_impl<int>(SYS_fcntl, fd, cmd,
79-
reinterpret_cast<void *>(arg));
80-
if (static_cast<unsigned long>(retVal) <= -4096UL)
81-
return fex.type == F_OWNER_PGRP ? -fex.pid : fex.pid;
82-
83-
libc_errno = -retVal;
84-
return -1;
85-
}
86-
// The general case
87-
default: {
88-
int retVal =
89-
syscall_impl<int>(SYS_fcntl, fd, cmd, reinterpret_cast<void *>(arg));
90-
if (retVal >= 0) {
91-
return retVal;
92-
}
93-
libc_errno = -retVal;
94-
return -1;
95-
}
96-
}
24+
return LIBC_NAMESPACE::internal::fcntl(fd, cmd, arg);
9725
}
26+
9827
} // namespace LIBC_NAMESPACE

libc/src/stdio/linux/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ add_entrypoint_object(
3232
HDRS
3333
../fdopen.h
3434
DEPENDS
35-
libc.include.fcntl
3635
libc.include.stdio
3736
libc.src.errno.errno
38-
libc.src.fcntl.fcntl
3937
libc.src.stdio.fseek
4038
libc.src.__support.File.platform_file
39+
libc.src.__support.OSUtil.osutil
4140
)

libc/src/stdio/linux/fdopen.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===-- Implementation of fprintf -------------------------------*- C++ -*-===//
1+
//===-- Implementation of fdopen --------------------------------*- C++ -*-===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -8,12 +8,11 @@
88

99
#include "src/stdio/fdopen.h"
1010

11-
#include "include/llvm-libc-macros/generic-error-number-macros.h"
12-
#include "include/llvm-libc-macros/linux/fcntl-macros.h"
11+
#include "hdr/errno_macros.h"
12+
#include "include/llvm-libc-macros/fcntl-macros.h"
1313
#include "src/__support/File/linux/file.h"
14+
#include "src/__support/OSUtil/fcntl.h"
1415
#include "src/errno/libc_errno.h"
15-
#include "src/fcntl/fcntl.h"
16-
#include "src/stdio/fseek.h"
1716

1817
namespace LIBC_NAMESPACE {
1918

@@ -25,7 +24,7 @@ LLVM_LIBC_FUNCTION(::FILE *, fdopen, (int fd, const char *mode)) {
2524
return nullptr;
2625
}
2726

28-
int fd_flags = LIBC_NAMESPACE::fcntl(fd, F_GETFL);
27+
int fd_flags = internal::fcntl(fd, F_GETFL);
2928
if (fd_flags == -1) {
3029
return nullptr;
3130
}
@@ -43,7 +42,8 @@ LLVM_LIBC_FUNCTION(::FILE *, fdopen, (int fd, const char *mode)) {
4342
if ((modeflags & static_cast<ModeFlags>(OpenMode::APPEND)) &&
4443
!(fd_flags & O_APPEND)) {
4544
do_seek = true;
46-
if (LIBC_NAMESPACE::fcntl(fd, F_SETFL, fd_flags | O_APPEND) == -1) {
45+
if (internal::fcntl(fd, F_SETFL,
46+
reinterpret_cast<void *>(fd_flags | O_APPEND)) == -1) {
4747
return nullptr;
4848
}
4949
}
@@ -58,19 +58,22 @@ LLVM_LIBC_FUNCTION(::FILE *, fdopen, (int fd, const char *mode)) {
5858
}
5959
}
6060
AllocChecker ac;
61-
auto *linux_file = new (ac)
61+
auto *file = new (ac)
6262
LinuxFile(fd, buffer, File::DEFAULT_BUFFER_SIZE, _IOFBF, true, modeflags);
6363
if (!ac) {
6464
libc_errno = ENOMEM;
6565
return nullptr;
6666
}
67-
auto *file = reinterpret_cast<::FILE *>(linux_file);
68-
if (do_seek && LIBC_NAMESPACE::fseek(file, 0, SEEK_END) != 0) {
69-
free(linux_file);
70-
return nullptr;
67+
if (do_seek) {
68+
auto result = file->seek(0, SEEK_END);
69+
if (!result.has_value()) {
70+
libc_errno = result.error();
71+
free(file);
72+
return nullptr;
73+
}
7174
}
7275

73-
return file;
76+
return reinterpret_cast<::FILE *>(file);
7477
}
7578

7679
} // namespace LIBC_NAMESPACE

libc/test/src/stdio/fdopen_test.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
//===-- Unittest for fcntl ------------------------------------------------===//
1+
//===-- Unittest for fdopen -----------------------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "include/llvm-libc-macros/linux/fcntl-macros.h"
109
#include "src/stdio/fdopen.h"
1110

11+
#include "include/llvm-libc-macros/fcntl-macros.h"
1212
#include "src/errno/libc_errno.h"
1313
#include "src/fcntl/open.h"
1414
#include "src/stdio/fclose.h"
@@ -37,6 +37,8 @@ TEST(LlvmLibcStdioFdopenTest, WriteAppendRead) {
3737
constexpr const char LLVM[] = "LLVM";
3838
int fd2 = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_RDWR);
3939
auto *fp2 = LIBC_NAMESPACE::fdopen(fd2, "a");
40+
ASSERT_ERRNO_SUCCESS();
41+
ASSERT_TRUE(nullptr != fp2);
4042
LIBC_NAMESPACE::fputs(LLVM, fp2);
4143
LIBC_NAMESPACE::fclose(fp2);
4244
ASSERT_ERRNO_SUCCESS();

0 commit comments

Comments
 (0)