Skip to content

Commit 5f70faa

Browse files
committed
Move the implementation of 'fdopen' to 'linux/file.cpp'
1 parent a535a9d commit 5f70faa

File tree

6 files changed

+67
-70
lines changed

6 files changed

+67
-70
lines changed

libc/src/__support/File/file.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ class File {
304304
// library.
305305
ErrorOr<File *> openfile(const char *path, const char *mode);
306306

307+
ErrorOr<File *> create_file_from_fd(int fd, const char *mode);
308+
307309
// The platform_file library should implement it if it relevant for that
308310
// platform.
309311
int get_fileno(File *f);

libc/src/__support/File/linux/file.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88

99
#include "file.h"
1010

11-
#include "src/__support/File/file.h"
12-
1311
#include "src/__support/CPP/new.h"
12+
#include "src/__support/File/file.h"
1413
#include "src/__support/File/linux/lseekImpl.h"
14+
#include "src/__support/OSUtil/fcntl.h"
1515
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
1616
#include "src/errno/libc_errno.h" // For error macros
1717

@@ -119,6 +119,60 @@ ErrorOr<File *> openfile(const char *path, const char *mode) {
119119
return file;
120120
}
121121

122+
ErrorOr<File *> create_file_from_fd(int fd, const char *mode) {
123+
using ModeFlags = File::ModeFlags;
124+
ModeFlags modeflags = File::mode_flags(mode);
125+
if (modeflags == 0) {
126+
return Error(EINVAL);
127+
}
128+
129+
int fd_flags = internal::fcntl(fd, F_GETFL);
130+
if (fd_flags == -1) {
131+
return Error(EBADF);
132+
}
133+
134+
using OpenMode = File::OpenMode;
135+
if (((fd_flags & O_ACCMODE) == O_RDONLY &&
136+
!(modeflags & static_cast<ModeFlags>(OpenMode::READ))) ||
137+
((fd_flags & O_ACCMODE) == O_WRONLY &&
138+
!(modeflags & static_cast<ModeFlags>(OpenMode::WRITE)))) {
139+
return Error(EINVAL);
140+
}
141+
142+
bool do_seek = false;
143+
if ((modeflags & static_cast<ModeFlags>(OpenMode::APPEND)) &&
144+
!(fd_flags & O_APPEND)) {
145+
do_seek = true;
146+
if (internal::fcntl(fd, F_SETFL,
147+
reinterpret_cast<void *>(fd_flags | O_APPEND)) == -1) {
148+
return Error(EBADF);
149+
}
150+
}
151+
152+
uint8_t *buffer;
153+
{
154+
AllocChecker ac;
155+
buffer = new (ac) uint8_t[File::DEFAULT_BUFFER_SIZE];
156+
if (!ac) {
157+
return Error(ENOMEM);
158+
}
159+
}
160+
AllocChecker ac;
161+
auto *file = new (ac)
162+
LinuxFile(fd, buffer, File::DEFAULT_BUFFER_SIZE, _IOFBF, true, modeflags);
163+
if (!ac) {
164+
return Error(ENOMEM);
165+
}
166+
if (do_seek) {
167+
auto result = file->seek(0, SEEK_END);
168+
if (!result.has_value()) {
169+
free(file);
170+
return Error(result.error());
171+
}
172+
}
173+
return file;
174+
}
175+
122176
int get_fileno(File *f) {
123177
auto *lf = reinterpret_cast<LinuxFile *>(f);
124178
return lf->get_fd();

libc/src/__support/OSUtil/fcntl.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
//===-- Implementation header of internal fcntl function ---------------*- C++
2-
//-*-===//
3-
//
1+
//===-- Implementation header of internal fcntl function ------------------===//
42
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
53
// See https://llvm.org/LICENSE.txt for license information.
64
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

libc/src/stdio/linux/CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ add_entrypoint_object(
3333
../fdopen.h
3434
DEPENDS
3535
libc.include.stdio
36-
libc.src.errno.errno
37-
libc.src.stdio.fseek
36+
libc.src.__support.File.file
3837
libc.src.__support.File.platform_file
39-
libc.src.__support.OSUtil.osutil
4038
)

libc/src/stdio/linux/fdopen.cpp

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,72 +8,18 @@
88

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

11-
#include "hdr/errno_macros.h"
12-
#include "include/llvm-libc-macros/fcntl-macros.h"
13-
#include "src/__support/File/linux/file.h"
14-
#include "src/__support/OSUtil/fcntl.h"
11+
#include "src/__support/File/file.h"
1512
#include "src/errno/libc_errno.h"
1613

1714
namespace LIBC_NAMESPACE {
1815

1916
LLVM_LIBC_FUNCTION(::FILE *, fdopen, (int fd, const char *mode)) {
20-
using ModeFlags = File::ModeFlags;
21-
ModeFlags modeflags = File::mode_flags(mode);
22-
if (modeflags == 0) {
23-
libc_errno = EINVAL;
17+
auto result = LIBC_NAMESPACE::create_file_from_fd(fd, mode);
18+
if (!result.has_value()) {
19+
libc_errno = result.error();
2420
return nullptr;
2521
}
26-
27-
int fd_flags = internal::fcntl(fd, F_GETFL);
28-
if (fd_flags == -1) {
29-
return nullptr;
30-
}
31-
32-
using OpenMode = File::OpenMode;
33-
if (((fd_flags & O_ACCMODE) == O_RDONLY &&
34-
!(modeflags & static_cast<ModeFlags>(OpenMode::READ))) ||
35-
((fd_flags & O_ACCMODE) == O_WRONLY &&
36-
!(modeflags & static_cast<ModeFlags>(OpenMode::WRITE)))) {
37-
libc_errno = EINVAL;
38-
return nullptr;
39-
}
40-
41-
bool do_seek = false;
42-
if ((modeflags & static_cast<ModeFlags>(OpenMode::APPEND)) &&
43-
!(fd_flags & O_APPEND)) {
44-
do_seek = true;
45-
if (internal::fcntl(fd, F_SETFL,
46-
reinterpret_cast<void *>(fd_flags | O_APPEND)) == -1) {
47-
return nullptr;
48-
}
49-
}
50-
51-
uint8_t *buffer;
52-
{
53-
AllocChecker ac;
54-
buffer = new (ac) uint8_t[File::DEFAULT_BUFFER_SIZE];
55-
if (!ac) {
56-
libc_errno = ENOMEM;
57-
return nullptr;
58-
}
59-
}
60-
AllocChecker ac;
61-
auto *file = new (ac)
62-
LinuxFile(fd, buffer, File::DEFAULT_BUFFER_SIZE, _IOFBF, true, modeflags);
63-
if (!ac) {
64-
libc_errno = ENOMEM;
65-
return nullptr;
66-
}
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-
}
74-
}
75-
76-
return reinterpret_cast<::FILE *>(file);
22+
return reinterpret_cast<::FILE *>(result.value());
7723
}
7824

7925
} // namespace LIBC_NAMESPACE

libc/test/src/stdio/fdopen_test.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

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

11-
#include "include/llvm-libc-macros/fcntl-macros.h"
11+
#include "hdr/fcntl_macros.h"
1212
#include "src/errno/libc_errno.h"
1313
#include "src/fcntl/open.h"
1414
#include "src/stdio/fclose.h"
@@ -47,8 +47,7 @@ TEST(LlvmLibcStdioFdopenTest, WriteAppendRead) {
4747
auto *fp3 = LIBC_NAMESPACE::fdopen(fd3, "r");
4848
char buffer[10];
4949
LIBC_NAMESPACE::fgets(buffer, sizeof(buffer), fp3);
50-
EXPECT_EQ('H', buffer[0]);
51-
EXPECT_EQ('M', buffer[8]);
50+
ASSERT_STREQ("HelloLLVM", buffer);
5251
LIBC_NAMESPACE::fclose(fp3);
5352
ASSERT_ERRNO_SUCCESS();
5453
}

0 commit comments

Comments
 (0)