[PATCH] CHECK_INIT() before _flockfile() for scanf/fscanf

Matt Johnson johnso87@crhc.illinois.edu
Fri Jul 15 15:15:00 GMT 2011


Hi all,
     I noticed a mailing list thread and commit from 2005 here 
http://sourceware.org/ml/newlib/2005/msg00088.html where some stdio 
functions were calling _flockfile() on a FILE * before initializing it.  
I think scanf/fscanf may have been missed by this initial patch; in the 
version of newlib I have (latest release), scanf() and fscanf() call 
directly into __svfscanf_r(), rather than going through the intermediate 
_vfscanf_r(), which contains the CHECK_INIT() call.  I was having 
problems where, if my program calls scanf() or fscanf(stdin, ...) before 
any *printf() calls, stdin got permanently locked up.  Here's a patch 
that fixed things for me:

diff --git a/lib/newlib/newlib/libc/stdio/fscanf.c 
b/lib/newlib/newlib/libc/stdio/fscanf.c
index c00a469..afbc2f0 100644
--- a/lib/newlib/newlib/libc/stdio/fscanf.c
+++ b/lib/newlib/newlib/libc/stdio/fscanf.c
@@ -45,7 +45,7 @@ fscanf(FILE *fp, fmt, va_alist)
  #else
    va_start (ap);
  #endif
-  ret = __svfscanf_r (_REENT, fp, fmt, ap);
+  ret = _vfscanf_r (_REENT, fp, fmt, ap);
    va_end (ap);
    return ret;
  }
@@ -71,7 +71,7 @@ _fscanf_r(ptr, FILE *fp, fmt, va_alist)
  #else
    va_start (ap);
  #endif
-  ret = __svfscanf_r (ptr, fp, fmt, ap);
+  ret = _vfscanf_r (ptr, fp, fmt, ap);
    va_end (ap);
    return (ret);
  }
diff --git a/lib/newlib/newlib/libc/stdio/scanf.c 
b/lib/newlib/newlib/libc/stdio/scanf.c
index cf1472b..68fd8fb 100644
--- a/lib/newlib/newlib/libc/stdio/scanf.c
+++ b/lib/newlib/newlib/libc/stdio/scanf.c
@@ -45,7 +45,7 @@ scanf(fmt, va_alist)
  #else
    va_start (ap);
  #endif
-  ret = __svfscanf_r (_REENT, _stdin_r (_REENT), fmt, ap);
+  ret = _vfscanf_r (_REENT, _stdin_r (_REENT), fmt, ap);
    va_end (ap);
    return ret;
  }
@@ -71,7 +71,7 @@ _scanf_r(ptr, fmt, va_alist)
  #else
    va_start (ap);
  #endif
-  ret = __svfscanf_r (ptr, _stdin_r (ptr), fmt, ap);
+  ret = _vfscanf_r (ptr, _stdin_r (ptr), fmt, ap);
    va_end (ap);
    return (ret);
  }


If these are in fact real problems, we may want to look through more of 
the stdio API to make sure there aren't any more paths by which we can 
call _flockfile() without CHECK_INIT().  Note also that 
_REENT_SMALL_CHECK_INIT() by itself is not enough, since it only covers 
the _REENT_SMALL case.

Thanks,
Matt



More information about the Newlib mailing list