Skip to content

Commit 9db0037

Browse files
author
Siva Chandra Reddy
committed
[libc] Add implementations of feof, ferror and clearerr.
The corresponding _unlocked functions have also been added. Reviewed By: lntue, michaelrj Differential Revision: https://reviews.llvm.org/D124311
1 parent 97b8a54 commit 9db0037

21 files changed

+499
-44
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,14 @@ if(LLVM_LIBC_FULL_BUILD)
251251
libc.src.stdlib.getenv
252252

253253
# stdio.h entrypoints
254+
libc.src.stdio.clearerr
255+
libc.src.stdio.clearerr_unlocked
254256
libc.src.stdio.fclose
255257
libc.src.stdio.flockfile
258+
libc.src.stdio.feof
259+
libc.src.stdio.feof_unlocked
260+
libc.src.stdio.ferror
261+
libc.src.stdio.ferror_unlocked
256262
libc.src.stdio.fflush
257263
libc.src.stdio.fopen
258264
libc.src.stdio.fopencookie

libc/spec/gnu_ext.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> {
7272
[CookieIOFunctionsT], // Types
7373
[], // Enumerations
7474
[
75+
FunctionSpec<
76+
"clearerr_unlocked",
77+
RetValSpec<VoidType>,
78+
[ArgSpec<FILEPtr>]
79+
>,
80+
FunctionSpec<
81+
"feof_unlocked",
82+
RetValSpec<IntType>,
83+
[ArgSpec<FILEPtr>]
84+
>,
85+
FunctionSpec<
86+
"ferror_unlocked",
87+
RetValSpec<IntType>,
88+
[ArgSpec<FILEPtr>]
89+
>,
7590
FunctionSpec<
7691
"fopencookie",
7792
RetValSpec<FILEPtr>,

libc/spec/stdc.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,26 @@ def StdC : StandardSpec<"stdc"> {
478478
],
479479
[], // Enumerations
480480
[
481+
FunctionSpec<
482+
"clearerr",
483+
RetValSpec<VoidType>,
484+
[ArgSpec<FILEPtr>]
485+
>,
481486
FunctionSpec<
482487
"fclose",
483488
RetValSpec<IntType>,
484489
[ArgSpec<FILEPtr>]
485490
>,
491+
FunctionSpec<
492+
"feof",
493+
RetValSpec<IntType>,
494+
[ArgSpec<FILEPtr>]
495+
>,
496+
FunctionSpec<
497+
"ferror",
498+
RetValSpec<IntType>,
499+
[ArgSpec<FILEPtr>]
500+
>,
486501
FunctionSpec<
487502
"fflush",
488503
RetValSpec<IntType>,

libc/src/__support/File/file.h

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ class File {
9797
bool eof;
9898
bool err;
9999

100+
// This is a convenience RAII class to lock and unlock file objects.
101+
class FileLock {
102+
File *file;
103+
104+
public:
105+
explicit FileLock(File *f) : file(f) { file->lock(); }
106+
107+
~FileLock() { file->unlock(); }
108+
109+
FileLock(const FileLock &) = delete;
110+
FileLock(FileLock &&) = delete;
111+
};
112+
100113
protected:
101114
bool write_allowed() const {
102115
return mode & (static_cast<ModeFlags>(OpenMode::WRITE) |
@@ -150,21 +163,17 @@ class File {
150163

151164
// Buffered write of |len| bytes from |data| under the file lock.
152165
size_t write(const void *data, size_t len) {
153-
lock();
154-
size_t ret = write_unlocked(data, len);
155-
unlock();
156-
return ret;
166+
FileLock l(this);
167+
return write_unlocked(data, len);
157168
}
158169

159170
// Buffered read of |len| bytes into |data| without the file lock.
160171
size_t read_unlocked(void *data, size_t len);
161172

162173
// Buffered read of |len| bytes into |data| under the file lock.
163174
size_t read(void *data, size_t len) {
164-
lock();
165-
size_t ret = read_unlocked(data, len);
166-
unlock();
167-
return ret;
175+
FileLock l(this);
176+
return read_unlocked(data, len);
168177
}
169178

170179
int seek(long offset, int whence);
@@ -184,26 +193,30 @@ class File {
184193
void lock() { mutex.lock(); }
185194
void unlock() { mutex.unlock(); }
186195

187-
bool error() const { return err; }
188-
void clearerr() { err = false; }
189-
bool iseof() const { return eof; }
196+
bool error_unlocked() const { return err; }
190197

191-
// Returns an bit map of flags corresponding to enumerations of
192-
// OpenMode, ContentType and CreateType.
193-
static ModeFlags mode_flags(const char *mode);
194-
};
198+
bool error() {
199+
FileLock l(this);
200+
return error_unlocked();
201+
}
195202

196-
// This is a convenience RAII class to lock and unlock file objects.
197-
class FileLock {
198-
File *file;
203+
void clearerr_unlocked() { err = false; }
199204

200-
public:
201-
explicit FileLock(File *f) : file(f) { file->lock(); }
205+
void clearerr() {
206+
FileLock l(this);
207+
clearerr_unlocked();
208+
}
209+
210+
bool iseof_unlocked() { return eof; }
202211

203-
~FileLock() { file->unlock(); }
212+
bool iseof() {
213+
FileLock l(this);
214+
return iseof_unlocked();
215+
}
204216

205-
FileLock(const FileLock &) = delete;
206-
FileLock(FileLock &&) = delete;
217+
// Returns an bit map of flags corresponding to enumerations of
218+
// OpenMode, ContentType and CreateType.
219+
static ModeFlags mode_flags(const char *mode);
207220
};
208221

209222
// The implementaiton of this function is provided by the platfrom_file

libc/src/stdio/CMakeLists.txt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,78 @@ add_entrypoint_object(
2424
libc.src.__support.File.platform_file
2525
)
2626

27+
add_entrypoint_object(
28+
clearerr
29+
SRCS
30+
clearerr.cpp
31+
HDRS
32+
clearerr.h
33+
DEPENDS
34+
libc.include.stdio
35+
libc.src.__support.File.file
36+
libc.src.__support.File.platform_file
37+
)
38+
39+
add_entrypoint_object(
40+
clearerr_unlocked
41+
SRCS
42+
clearerr_unlocked.cpp
43+
HDRS
44+
clearerr_unlocked.h
45+
DEPENDS
46+
libc.include.stdio
47+
libc.src.__support.File.file
48+
libc.src.__support.File.platform_file
49+
)
50+
51+
add_entrypoint_object(
52+
feof
53+
SRCS
54+
feof.cpp
55+
HDRS
56+
feof.h
57+
DEPENDS
58+
libc.include.stdio
59+
libc.src.__support.File.file
60+
libc.src.__support.File.platform_file
61+
)
62+
63+
add_entrypoint_object(
64+
feof_unlocked
65+
SRCS
66+
feof_unlocked.cpp
67+
HDRS
68+
feof_unlocked.h
69+
DEPENDS
70+
libc.include.stdio
71+
libc.src.__support.File.file
72+
libc.src.__support.File.platform_file
73+
)
74+
75+
add_entrypoint_object(
76+
ferror
77+
SRCS
78+
ferror.cpp
79+
HDRS
80+
ferror.h
81+
DEPENDS
82+
libc.include.stdio
83+
libc.src.__support.File.file
84+
libc.src.__support.File.platform_file
85+
)
86+
87+
add_entrypoint_object(
88+
ferror_unlocked
89+
SRCS
90+
ferror_unlocked.cpp
91+
HDRS
92+
ferror_unlocked.h
93+
DEPENDS
94+
libc.include.stdio
95+
libc.src.__support.File.file
96+
libc.src.__support.File.platform_file
97+
)
98+
2799
add_entrypoint_object(
28100
fflush
29101
SRCS

libc/src/stdio/clearerr.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of clearerr ----------------------------------------===//
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/stdio/clearerr.h"
10+
#include "src/__support/File/file.h"
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
LLVM_LIBC_FUNCTION(void, clearerr, (::FILE * stream)) {
17+
reinterpret_cast<__llvm_libc::File *>(stream)->clearerr();
18+
}
19+
20+
} // namespace __llvm_libc

libc/src/stdio/clearerr.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header of clearerr -----------------------*- 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_STDIO_CLEARERR_H
10+
#define LLVM_LIBC_SRC_STDIO_CLEARERR_H
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
void clearerr(::FILE *stream);
17+
18+
} // namespace __llvm_libc
19+
20+
#endif // LLVM_LIBC_SRC_STDIO_CLEARERR_H

libc/src/stdio/clearerr_unlocked.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of clearerr_unlocked -------------------------------===//
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/stdio/clearerr_unlocked.h"
10+
#include "src/__support/File/file.h"
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
LLVM_LIBC_FUNCTION(void, clearerr_unlocked, (::FILE * stream)) {
17+
reinterpret_cast<__llvm_libc::File *>(stream)->clearerr_unlocked();
18+
}
19+
20+
} // namespace __llvm_libc

libc/src/stdio/clearerr_unlocked.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header of clearerr_unlocked --------------*- 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_STDIO_CLEARERR_UNLOCKED_H
10+
#define LLVM_LIBC_SRC_STDIO_CLEARERR_UNLOCKED_H
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
void clearerr_unlocked(::FILE *stream);
17+
18+
} // namespace __llvm_libc
19+
20+
#endif // LLVM_LIBC_SRC_STDIO_CLEARERR_UNLOCKED_H

libc/src/stdio/feof.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of feof --------------------------------------------===//
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/stdio/feof.h"
10+
#include "src/__support/File/file.h"
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
LLVM_LIBC_FUNCTION(int, feof, (::FILE * stream)) {
17+
return reinterpret_cast<__llvm_libc::File *>(stream)->iseof();
18+
}
19+
20+
} // namespace __llvm_libc

0 commit comments

Comments
 (0)