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

via libc-commits libc-commits at lists.llvm.org
Mon Sep 25 15:00:06 PDT 2023


Author: michaelrj-google
Date: 2023-09-25T15:00:03-07:00
New Revision: 23552fe22047f47f22c959579a3799530ef2a405

URL: https://github.com/llvm/llvm-project/commit/23552fe22047f47f22c959579a3799530ef2a405
DIFF: https://github.com/llvm/llvm-project/commit/23552fe22047f47f22c959579a3799530ef2a405.diff

LOG: [libc] Acquire the lock for scanf files (#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.

Added: 
    

Modified: 
    libc/src/stdio/scanf_core/vfscanf_internal.h

Removed: 
    


################################################################################
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