Author: kevans
Date: Thu Jan 30 03:31:16 2020
New Revision: 357284
URL: https://svnweb.freebsd.org/changeset/base/357284

Log:
  stdio: provide _unlocked variants of fflush, fputc, fputs, fread, fwrite
  
  fflush_unlocked is currently desired in ports by sysutils/metalog, and
  redefined as the locked fflush.
  
  fputc_unlocked, fputs_unlocked, fread_unlocked, and fwrite_unlocked are
  currently desired in ports by devel/elfutils, and redefined as the locked
  fputs, fread, and fwrite respectively.
  
  Reviewed by:  kib
  MFC after:    2 weeks
  Differential Revision:        https://reviews.freebsd.org/D23336

Modified:
  head/include/stdio.h
  head/lib/libc/stdio/Makefile.inc
  head/lib/libc/stdio/Symbol.map
  head/lib/libc/stdio/fflush.3
  head/lib/libc/stdio/fflush.c
  head/lib/libc/stdio/fputc.c
  head/lib/libc/stdio/fputs.3
  head/lib/libc/stdio/fputs.c
  head/lib/libc/stdio/fread.3
  head/lib/libc/stdio/fread.c
  head/lib/libc/stdio/fwrite.c
  head/lib/libc/stdio/putc.3

Modified: head/include/stdio.h
==============================================================================
--- head/include/stdio.h        Thu Jan 30 03:01:00 2020        (r357283)
+++ head/include/stdio.h        Thu Jan 30 03:31:16 2020        (r357284)
@@ -346,7 +346,12 @@ int         putchar_unlocked(int);
 void    clearerr_unlocked(FILE *);
 int     feof_unlocked(FILE *);
 int     ferror_unlocked(FILE *);
+int     fflush_unlocked(FILE *);
 int     fileno_unlocked(FILE *);
+int     fputs_unlocked(const char * __restrict, FILE * __restrict);
+size_t  fread_unlocked(void * __restrict, size_t, size_t, FILE * __restrict);
+size_t  fwrite_unlocked(const void * __restrict, size_t, size_t,
+    FILE * __restrict);
 #endif
 
 #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 500
@@ -507,10 +512,11 @@ extern int __isthreaded;
  * See ISO/IEC 9945-1 ANSI/IEEE Std 1003.1 Second Edition 1996-07-12
  * B.8.2.7 for the rationale behind the *_unlocked() macros.
  */
+#define        clearerr_unlocked(p)    __sclearerr(p)
 #define        feof_unlocked(p)        __sfeof(p)
 #define        ferror_unlocked(p)      __sferror(p)
-#define        clearerr_unlocked(p)    __sclearerr(p)
 #define        fileno_unlocked(p)      __sfileno(p)
+#define        fputc_unlocked(s, p)    __sputc(s, p)
 #endif
 #if __POSIX_VISIBLE >= 199506
 #define        getc_unlocked(fp)       __sgetc(fp)

Modified: head/lib/libc/stdio/Makefile.inc
==============================================================================
--- head/lib/libc/stdio/Makefile.inc    Thu Jan 30 03:01:00 2020        
(r357283)
+++ head/lib/libc/stdio/Makefile.inc    Thu Jan 30 03:31:16 2020        
(r357284)
@@ -48,13 +48,17 @@ MLINKS+=ferror.3 ferror_unlocked.3 \
        ferror.3 clearerr.3 ferror.3 clearerr_unlocked.3 \
        ferror.3 feof.3 ferror.3 feof_unlocked.3 \
        ferror.3 fileno.3 ferror.3 fileno_unlocked.3
-MLINKS+=fflush.3 fpurge.3
+MLINKS+=fflush.3 fflush_unlocked.3 \
+       fflush.3 fpurge.3
 MLINKS+=fgets.3 gets.3
 MLINKS+=fgets.3 gets_s.3
 MLINKS+=flockfile.3 ftrylockfile.3 flockfile.3 funlockfile.3
 MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3 fopen.3 fmemopen.3
-MLINKS+=fputs.3 puts.3
-MLINKS+=fread.3 fwrite.3
+MLINKS+=fputs.3 fputs_unlocked.3 \
+       fputs.3 puts.3
+MLINKS+=fread.3 fread_unlocked.3 \
+       fread.3 fwrite.3 \
+       fread.3 fwrite_unlocked.3
 MLINKS+=fseek.3 fgetpos.3 fseek.3 fseeko.3 fseek.3 fsetpos.3 fseek.3 ftell.3 \
        fseek.3 ftello.3 fseek.3 rewind.3
 MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3

Modified: head/lib/libc/stdio/Symbol.map
==============================================================================
--- head/lib/libc/stdio/Symbol.map      Thu Jan 30 03:01:00 2020        
(r357283)
+++ head/lib/libc/stdio/Symbol.map      Thu Jan 30 03:31:16 2020        
(r357284)
@@ -172,6 +172,10 @@ FBSD_1.5 {
 };
 
 FBSD_1.6 {
+       fflush_unlocked;
+       fputs_unlocked;
+       fread_unlocked;
+       fwrite_unlocked;
        mkostempsat;
 };
 

Modified: head/lib/libc/stdio/fflush.3
==============================================================================
--- head/lib/libc/stdio/fflush.3        Thu Jan 30 03:01:00 2020        
(r357283)
+++ head/lib/libc/stdio/fflush.3        Thu Jan 30 03:31:16 2020        
(r357284)
@@ -32,11 +32,12 @@
 .\"     @(#)fflush.3   8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd December 25, 2017
+.Dd January 23, 2020
 .Dt FFLUSH 3
 .Os
 .Sh NAME
 .Nm fflush ,
+.Nm fflush_unlocked ,
 .Nm fpurge
 .Nd flush a stream
 .Sh LIBRARY
@@ -46,6 +47,8 @@
 .Ft int
 .Fn fflush "FILE *stream"
 .Ft int
+.Fn fflush_unlocked "FILE *stream"
+.Ft int
 .Fn fpurge "FILE *stream"
 .Sh DESCRIPTION
 The function
@@ -63,6 +66,16 @@ argument is
 flushes
 .Em all
 open output streams.
+.Pp
+The
+.Fn fflush_unlocked
+function is equivalent to
+.Fn fflush ,
+except that the caller is responsible for locking the stream with
+.Xr flockfile 3
+before calling it.
+This function may be used to avoid the overhead of locking the stream and to
+prevent races when multiple threads are operating on the same stream.
 .Pp
 The function
 .Fn fpurge

Modified: head/lib/libc/stdio/fflush.c
==============================================================================
--- head/lib/libc/stdio/fflush.c        Thu Jan 30 03:01:00 2020        
(r357283)
+++ head/lib/libc/stdio/fflush.c        Thu Jan 30 03:31:16 2020        
(r357284)
@@ -100,6 +100,8 @@ __fflush(FILE *fp)
        return (retval);
 }
 
+__weak_reference(__fflush, fflush_unlocked);
+
 int
 __sflush(FILE *fp)
 {

Modified: head/lib/libc/stdio/fputc.c
==============================================================================
--- head/lib/libc/stdio/fputc.c Thu Jan 30 03:01:00 2020        (r357283)
+++ head/lib/libc/stdio/fputc.c Thu Jan 30 03:31:16 2020        (r357284)
@@ -44,6 +44,8 @@ __FBSDID("$FreeBSD$");
 #include "local.h"
 #include "libc_private.h"
 
+#undef fputc_unlocked
+
 int
 fputc(int c, FILE *fp)
 {

Modified: head/lib/libc/stdio/fputs.3
==============================================================================
--- head/lib/libc/stdio/fputs.3 Thu Jan 30 03:01:00 2020        (r357283)
+++ head/lib/libc/stdio/fputs.3 Thu Jan 30 03:31:16 2020        (r357284)
@@ -32,11 +32,12 @@
 .\"     @(#)fputs.3    8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd June 4, 1993
+.Dd January 23, 2020
 .Dt FPUTS 3
 .Os
 .Sh NAME
 .Nm fputs ,
+.Nm fputs_unlocked ,
 .Nm puts
 .Nd output a line to a stream
 .Sh LIBRARY
@@ -46,6 +47,8 @@
 .Ft int
 .Fn fputs "const char *str" "FILE *stream"
 .Ft int
+.Fn fputs_unlocked "const char *str" "FILE *stream"
+.Ft int
 .Fn puts "const char *str"
 .Sh DESCRIPTION
 The function
@@ -57,6 +60,16 @@ to the stream pointed to by
 .\" The terminating
 .\" .Dv NUL
 .\" character is not written.
+.Pp
+The
+.Fn fputs_unlocked
+function is equivalent to
+.Fn fputs ,
+except that the caller is responsible for locking the stream with
+.Xr flockfile 3
+before calling it.
+This function may be used to avoid the overhead of locking the stream and to
+prevent races when multiple threads are operating on the same stream.
 .Pp
 The function
 .Fn puts

Modified: head/lib/libc/stdio/fputs.c
==============================================================================
--- head/lib/libc/stdio/fputs.c Thu Jan 30 03:01:00 2020        (r357283)
+++ head/lib/libc/stdio/fputs.c Thu Jan 30 03:31:16 2020        (r357284)
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
  * Write the given string to the given file.
  */
 int
-fputs(const char * __restrict s, FILE * __restrict fp)
+fputs_unlocked(const char * __restrict s, FILE * __restrict fp)
 {
        int retval;
        struct __suio uio;
@@ -61,11 +61,20 @@ fputs(const char * __restrict s, FILE * __restrict fp)
        uio.uio_resid = iov.iov_len = strlen(s);
        uio.uio_iov = &iov;
        uio.uio_iovcnt = 1;
-       FLOCKFILE_CANCELSAFE(fp);
        ORIENT(fp, -1);
        retval = __sfvwrite(fp, &uio);
-       FUNLOCKFILE_CANCELSAFE();
        if (retval == 0)
                return (iov.iov_len > INT_MAX ? INT_MAX : iov.iov_len);
+       return (retval);
+}
+
+int
+fputs(const char * __restrict s, FILE * __restrict fp)
+{
+       int retval;
+
+       FLOCKFILE_CANCELSAFE(fp);
+       retval = fputs_unlocked(s, fp);
+       FUNLOCKFILE_CANCELSAFE();
        return (retval);
 }

Modified: head/lib/libc/stdio/fread.3
==============================================================================
--- head/lib/libc/stdio/fread.3 Thu Jan 30 03:01:00 2020        (r357283)
+++ head/lib/libc/stdio/fread.3 Thu Jan 30 03:31:16 2020        (r357284)
@@ -32,12 +32,14 @@
 .\"     @(#)fread.3    8.2 (Berkeley) 3/8/94
 .\" $FreeBSD$
 .\"
-.Dd March 8, 1994
+.Dd January 23, 2020
 .Dt FREAD 3
 .Os
 .Sh NAME
 .Nm fread ,
-.Nm fwrite
+.Nm fread_unlocked ,
+.Nm fwrite ,
+.Nm fwrite_unlocked
 .Nd binary stream input/output
 .Sh LIBRARY
 .Lb libc
@@ -46,7 +48,11 @@
 .Ft size_t
 .Fn fread "void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict 
stream"
 .Ft size_t
+.Fn fread_unlocked "void * restrict ptr" "size_t size" "size_t nmemb" "FILE * 
restrict stream"
+.Ft size_t
 .Fn fwrite "const void * restrict ptr" "size_t size" "size_t nmemb" "FILE * 
restrict stream"
+.Ft size_t
+.Fn fwrite_unlocked "const void * restrict ptr" "size_t size" "size_t nmemb" 
"FILE * restrict stream"
 .Sh DESCRIPTION
 The function
 .Fn fread
@@ -69,6 +75,21 @@ bytes long, to the stream pointed to by
 .Fa stream ,
 obtaining them from the location given by
 .Fa ptr .
+.Pp
+The
+.Fn fread_unlocked
+and
+.Fn fwrite_unlocked
+functions are equivalent to
+.Fn fread
+and
+.Fn fwrite
+respectively, except that the caller is responsible for locking the stream
+with
+.Xr flockfile 3
+before calling them.
+These functions may be used to avoid the overhead of locking the stream
+and to prevent races when multiple threads are operating on the same stream.
 .Sh RETURN VALUES
 The functions
 .Fn fread

Modified: head/lib/libc/stdio/fread.c
==============================================================================
--- head/lib/libc/stdio/fread.c Thu Jan 30 03:01:00 2020        (r357283)
+++ head/lib/libc/stdio/fread.c Thu Jan 30 03:31:16 2020        (r357284)
@@ -115,3 +115,5 @@ __fread(void * __restrict buf, size_t size, size_t cou
        fp->_p += resid;
        return (count);
 }
+
+__weak_reference(__fread, fread_unlocked);

Modified: head/lib/libc/stdio/fwrite.c
==============================================================================
--- head/lib/libc/stdio/fwrite.c        Thu Jan 30 03:01:00 2020        
(r357283)
+++ head/lib/libc/stdio/fwrite.c        Thu Jan 30 03:31:16 2020        
(r357284)
@@ -52,7 +52,8 @@ __FBSDID("$FreeBSD$");
  * Return the number of whole objects written.
  */
 size_t
-fwrite(const void * __restrict buf, size_t size, size_t count, FILE * 
__restrict fp)
+fwrite_unlocked(const void * __restrict buf, size_t size, size_t count,
+    FILE * __restrict fp)
 {
        size_t n;
        struct __suio uio;
@@ -84,7 +85,6 @@ fwrite(const void * __restrict buf, size_t size, size_
        uio.uio_iov = &iov;
        uio.uio_iovcnt = 1;
 
-       FLOCKFILE_CANCELSAFE(fp);
        ORIENT(fp, -1);
        /*
         * The usual case is success (__sfvwrite returns 0);
@@ -93,6 +93,17 @@ fwrite(const void * __restrict buf, size_t size, size_
         */
        if (__sfvwrite(fp, &uio) != 0)
            count = (n - uio.uio_resid) / size;
-       FUNLOCKFILE_CANCELSAFE();
        return (count);
+}
+
+size_t
+fwrite(const void * __restrict buf, size_t size, size_t count,
+    FILE * __restrict fp)
+{
+       size_t n;
+
+       FLOCKFILE_CANCELSAFE(fp);
+       n = fwrite_unlocked(buf, size, count, fp);
+       FUNLOCKFILE_CANCELSAFE();
+       return (n);
 }

Modified: head/lib/libc/stdio/putc.3
==============================================================================
--- head/lib/libc/stdio/putc.3  Thu Jan 30 03:01:00 2020        (r357283)
+++ head/lib/libc/stdio/putc.3  Thu Jan 30 03:31:16 2020        (r357284)
@@ -32,11 +32,12 @@
 .\"     @(#)putc.3     8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd January 10, 2003
+.Dd January 23, 2020
 .Dt PUTC 3
 .Os
 .Sh NAME
 .Nm fputc ,
+.Nm fputc_unlocked ,
 .Nm putc ,
 .Nm putc_unlocked ,
 .Nm putchar ,
@@ -50,6 +51,8 @@
 .Ft int
 .Fn fputc "int c" "FILE *stream"
 .Ft int
+.Fn fputc_unlocked "int c" "FILE *stream"
+.Ft int
 .Fn putc "int c" "FILE *stream"
 .Ft int
 .Fn putc_unlocked "int c" "FILE *stream"
@@ -97,11 +100,13 @@ to the named output
 .Fa stream .
 .Pp
 The
-.Fn putc_unlocked
+.Fn fputc_unlocked ,
+.Fn putc_unlocked ,
 and
 .Fn putchar_unlocked
 functions are equivalent to
-.Fn putc
+.Fn fputc ,
+.Fn putc ,
 and
 .Fn putchar
 respectively,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to