[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:30:03 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

<details>
<summary>Changes</summary>

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.


---
Full diff: https://github.com/llvm/llvm-project/pull/67357.diff


1 Files Affected:

- (modified) libc/src/stdio/scanf_core/vfscanf_internal.h (+19-3) 


``````````diff
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;
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/67357


More information about the libc-commits mailing list