Skip to content

Commit 23552fe

Browse files
[libc] Acquire the lock for scanf files (llvm#67357)
When creating the new scanf reader design, I forgot to add back the calls to flockfile and funlockfile in vfscanf_internal. This patch fixes that, and also changes the system file version to use the normal variants since ungetc_unlocked isn't always available.
1 parent 580d26a commit 23552fe

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

libc/src/stdio/scanf_core/vfscanf_internal.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ namespace internal {
2222

2323
#ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
2424

25+
LIBC_INLINE void flockfile(FILE *f) {
26+
reinterpret_cast<__llvm_libc::File *>(f)->lock();
27+
}
28+
29+
LIBC_INLINE void funlockfile(FILE *f) {
30+
reinterpret_cast<__llvm_libc::File *>(f)->unlock();
31+
}
32+
2533
LIBC_INLINE int getc(void *f) {
2634
unsigned char c;
2735
auto result = reinterpret_cast<__llvm_libc::File *>(f)->read_unlocked(&c, 1);
@@ -33,7 +41,7 @@ LIBC_INLINE int getc(void *f) {
3341
}
3442

3543
LIBC_INLINE void ungetc(int c, void *f) {
36-
reinterpret_cast<__llvm_libc::File *>(f)->ungetc(c);
44+
reinterpret_cast<__llvm_libc::File *>(f)->ungetc_unlocked(c);
3745
}
3846

3947
LIBC_INLINE int ferror_unlocked(FILE *f) {
@@ -42,13 +50,19 @@ LIBC_INLINE int ferror_unlocked(FILE *f) {
4250

4351
#else // defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE)
4452

53+
// Since ungetc_unlocked isn't always available, we don't acquire the lock for
54+
// system files.
55+
LIBC_INLINE void flockfile(::FILE *) { return; }
56+
57+
LIBC_INLINE void funlockfile(::FILE *) { return; }
58+
4559
LIBC_INLINE int getc(void *f) { return ::getc(reinterpret_cast<::FILE *>(f)); }
4660

4761
LIBC_INLINE void ungetc(int c, void *f) {
4862
::ungetc(c, reinterpret_cast<::FILE *>(f));
4963
}
5064

51-
LIBC_INLINE int ferror_unlocked(::FILE *f) { return ::ferror_unlocked(f); }
65+
LIBC_INLINE int ferror_unlocked(::FILE *f) { return ::ferror(f); }
5266

5367
#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
5468

@@ -59,10 +73,12 @@ namespace scanf_core {
5973
LIBC_INLINE int vfscanf_internal(::FILE *__restrict stream,
6074
const char *__restrict format,
6175
internal::ArgList &args) {
76+
internal::flockfile(stream);
6277
scanf_core::Reader reader(stream, &internal::getc, internal::ungetc);
6378
int retval = scanf_core::scanf_main(&reader, format, args);
6479
if (retval == 0 && internal::ferror_unlocked(stream))
65-
return EOF;
80+
retval = EOF;
81+
internal::funlockfile(stream);
6682

6783
return retval;
6884
}

0 commit comments

Comments
 (0)