[libc-commits] [libc] [libc] Acquire the lock for scanf files (PR #67357)

via libc-commits libc-commits at lists.llvm.org
Mon Sep 25 11:29:04 PDT 2023


https://github.com/michaelrj-google created https://github.com/llvm/llvm-project/pull/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.


>From 4236c91332417267489d80f78da414e45d6d721e Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Mon, 25 Sep 2023 11:24:52 -0700
Subject: [PATCH] [libc] Acquire the lock for scanf files

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.
---
 libc/src/stdio/scanf_core/vfscanf_internal.h | 22 +++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/libc/src/stdio/scanf_core/vfscanf_internal.h b/libc/src/stdio/scanf_core/vfscanf_internal.h
index 68d03d02663b970..715d31ab13eb075 100644
--- a/libc/src/stdio/scanf_core/vfscanf_internal.h
+++ b/libc/src/stdio/scanf_core/vfscanf_internal.h
@@ -22,6 +22,14 @@ namespace internal {
 
 #ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE
 
+LIBC_INLINE void flockfile(FILE *f) {
+  reinterpret_cast<__llvm_libc::File *>(f)->lock();
+}
+
+LIBC_INLINE void funlockfile(FILE *f) {
+  reinterpret_cast<__llvm_libc::File *>(f)->unlock();
+}
+
 LIBC_INLINE int getc(void *f) {
   unsigned char c;
   auto result = reinterpret_cast<__llvm_libc::File *>(f)->read_unlocked(&c, 1);
@@ -33,7 +41,7 @@ LIBC_INLINE int getc(void *f) {
 }
 
 LIBC_INLINE void ungetc(int c, void *f) {
-  reinterpret_cast<__llvm_libc::File *>(f)->ungetc(c);
+  reinterpret_cast<__llvm_libc::File *>(f)->ungetc_unlocked(c);
 }
 
 LIBC_INLINE int ferror_unlocked(FILE *f) {
@@ -42,13 +50,19 @@ LIBC_INLINE int ferror_unlocked(FILE *f) {
 
 #else // defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE)
 
+// Since ungetc_unlocked isn't always available, we don't acquire the lock for
+// system files.
+LIBC_INLINE void flockfile(::FILE *) { return; }
+
+LIBC_INLINE void funlockfile(::FILE *) { return; }
+
 LIBC_INLINE int getc(void *f) { return ::getc(reinterpret_cast<::FILE *>(f)); }
 
 LIBC_INLINE void ungetc(int c, void *f) {
   ::ungetc(c, reinterpret_cast<::FILE *>(f));
 }
 
-LIBC_INLINE int ferror_unlocked(::FILE *f) { return ::ferror_unlocked(f); }
+LIBC_INLINE int ferror_unlocked(::FILE *f) { return ::ferror(f); }
 
 #endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
 
@@ -59,10 +73,12 @@ namespace scanf_core {
 LIBC_INLINE int vfscanf_internal(::FILE *__restrict stream,
                                  const char *__restrict format,
                                  internal::ArgList &args) {
+  internal::flockfile(stream);
   scanf_core::Reader reader(stream, &internal::getc, internal::ungetc);
   int retval = scanf_core::scanf_main(&reader, format, args);
   if (retval == 0 && internal::ferror_unlocked(stream))
-    return EOF;
+    retval = EOF;
+  internal::funlockfile(stream);
 
   return retval;
 }



More information about the libc-commits mailing list