mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-14 12:23:58 +00:00
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
This commit is contained in:
parent
f2c462994d
commit
12fe218f0b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=357284
|
@ -346,7 +346,12 @@ int putchar_unlocked(int);
|
||||||
void clearerr_unlocked(FILE *);
|
void clearerr_unlocked(FILE *);
|
||||||
int feof_unlocked(FILE *);
|
int feof_unlocked(FILE *);
|
||||||
int ferror_unlocked(FILE *);
|
int ferror_unlocked(FILE *);
|
||||||
|
int fflush_unlocked(FILE *);
|
||||||
int fileno_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
|
#endif
|
||||||
|
|
||||||
#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 500
|
#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
|
* 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.
|
* B.8.2.7 for the rationale behind the *_unlocked() macros.
|
||||||
*/
|
*/
|
||||||
|
#define clearerr_unlocked(p) __sclearerr(p)
|
||||||
#define feof_unlocked(p) __sfeof(p)
|
#define feof_unlocked(p) __sfeof(p)
|
||||||
#define ferror_unlocked(p) __sferror(p)
|
#define ferror_unlocked(p) __sferror(p)
|
||||||
#define clearerr_unlocked(p) __sclearerr(p)
|
|
||||||
#define fileno_unlocked(p) __sfileno(p)
|
#define fileno_unlocked(p) __sfileno(p)
|
||||||
|
#define fputc_unlocked(s, p) __sputc(s, p)
|
||||||
#endif
|
#endif
|
||||||
#if __POSIX_VISIBLE >= 199506
|
#if __POSIX_VISIBLE >= 199506
|
||||||
#define getc_unlocked(fp) __sgetc(fp)
|
#define getc_unlocked(fp) __sgetc(fp)
|
||||||
|
|
|
@ -48,13 +48,17 @@ MLINKS+=ferror.3 ferror_unlocked.3 \
|
||||||
ferror.3 clearerr.3 ferror.3 clearerr_unlocked.3 \
|
ferror.3 clearerr.3 ferror.3 clearerr_unlocked.3 \
|
||||||
ferror.3 feof.3 ferror.3 feof_unlocked.3 \
|
ferror.3 feof.3 ferror.3 feof_unlocked.3 \
|
||||||
ferror.3 fileno.3 ferror.3 fileno_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.3
|
||||||
MLINKS+=fgets.3 gets_s.3
|
MLINKS+=fgets.3 gets_s.3
|
||||||
MLINKS+=flockfile.3 ftrylockfile.3 flockfile.3 funlockfile.3
|
MLINKS+=flockfile.3 ftrylockfile.3 flockfile.3 funlockfile.3
|
||||||
MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3 fopen.3 fmemopen.3
|
MLINKS+=fopen.3 fdopen.3 fopen.3 freopen.3 fopen.3 fmemopen.3
|
||||||
MLINKS+=fputs.3 puts.3
|
MLINKS+=fputs.3 fputs_unlocked.3 \
|
||||||
MLINKS+=fread.3 fwrite.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 \
|
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
|
fseek.3 ftello.3 fseek.3 rewind.3
|
||||||
MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3
|
MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3
|
||||||
|
|
|
@ -172,6 +172,10 @@ FBSD_1.5 {
|
||||||
};
|
};
|
||||||
|
|
||||||
FBSD_1.6 {
|
FBSD_1.6 {
|
||||||
|
fflush_unlocked;
|
||||||
|
fputs_unlocked;
|
||||||
|
fread_unlocked;
|
||||||
|
fwrite_unlocked;
|
||||||
mkostempsat;
|
mkostempsat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,12 @@
|
||||||
.\" @(#)fflush.3 8.1 (Berkeley) 6/4/93
|
.\" @(#)fflush.3 8.1 (Berkeley) 6/4/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd December 25, 2017
|
.Dd January 23, 2020
|
||||||
.Dt FFLUSH 3
|
.Dt FFLUSH 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm fflush ,
|
.Nm fflush ,
|
||||||
|
.Nm fflush_unlocked ,
|
||||||
.Nm fpurge
|
.Nm fpurge
|
||||||
.Nd flush a stream
|
.Nd flush a stream
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
|
@ -46,6 +47,8 @@
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn fflush "FILE *stream"
|
.Fn fflush "FILE *stream"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn fflush_unlocked "FILE *stream"
|
||||||
|
.Ft int
|
||||||
.Fn fpurge "FILE *stream"
|
.Fn fpurge "FILE *stream"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The function
|
The function
|
||||||
|
@ -64,6 +67,16 @@ flushes
|
||||||
.Em all
|
.Em all
|
||||||
open output streams.
|
open output streams.
|
||||||
.Pp
|
.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
|
The function
|
||||||
.Fn fpurge
|
.Fn fpurge
|
||||||
erases any input or output buffered in the given
|
erases any input or output buffered in the given
|
||||||
|
|
|
@ -100,6 +100,8 @@ __fflush(FILE *fp)
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__weak_reference(__fflush, fflush_unlocked);
|
||||||
|
|
||||||
int
|
int
|
||||||
__sflush(FILE *fp)
|
__sflush(FILE *fp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,8 @@ __FBSDID("$FreeBSD$");
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
#include "libc_private.h"
|
#include "libc_private.h"
|
||||||
|
|
||||||
|
#undef fputc_unlocked
|
||||||
|
|
||||||
int
|
int
|
||||||
fputc(int c, FILE *fp)
|
fputc(int c, FILE *fp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,11 +32,12 @@
|
||||||
.\" @(#)fputs.3 8.1 (Berkeley) 6/4/93
|
.\" @(#)fputs.3 8.1 (Berkeley) 6/4/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 4, 1993
|
.Dd January 23, 2020
|
||||||
.Dt FPUTS 3
|
.Dt FPUTS 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm fputs ,
|
.Nm fputs ,
|
||||||
|
.Nm fputs_unlocked ,
|
||||||
.Nm puts
|
.Nm puts
|
||||||
.Nd output a line to a stream
|
.Nd output a line to a stream
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
|
@ -46,6 +47,8 @@
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn fputs "const char *str" "FILE *stream"
|
.Fn fputs "const char *str" "FILE *stream"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn fputs_unlocked "const char *str" "FILE *stream"
|
||||||
|
.Ft int
|
||||||
.Fn puts "const char *str"
|
.Fn puts "const char *str"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The function
|
The function
|
||||||
|
@ -58,6 +61,16 @@ to the stream pointed to by
|
||||||
.\" .Dv NUL
|
.\" .Dv NUL
|
||||||
.\" character is not written.
|
.\" character is not written.
|
||||||
.Pp
|
.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
|
The function
|
||||||
.Fn puts
|
.Fn puts
|
||||||
writes the string
|
writes the string
|
||||||
|
|
|
@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||||
* Write the given string to the given file.
|
* Write the given string to the given file.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
fputs(const char * __restrict s, FILE * __restrict fp)
|
fputs_unlocked(const char * __restrict s, FILE * __restrict fp)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
struct __suio uio;
|
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_resid = iov.iov_len = strlen(s);
|
||||||
uio.uio_iov = &iov;
|
uio.uio_iov = &iov;
|
||||||
uio.uio_iovcnt = 1;
|
uio.uio_iovcnt = 1;
|
||||||
FLOCKFILE_CANCELSAFE(fp);
|
|
||||||
ORIENT(fp, -1);
|
ORIENT(fp, -1);
|
||||||
retval = __sfvwrite(fp, &uio);
|
retval = __sfvwrite(fp, &uio);
|
||||||
FUNLOCKFILE_CANCELSAFE();
|
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
return (iov.iov_len > INT_MAX ? INT_MAX : iov.iov_len);
|
return (iov.iov_len > INT_MAX ? INT_MAX : iov.iov_len);
|
||||||
return (retval);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -32,12 +32,14 @@
|
||||||
.\" @(#)fread.3 8.2 (Berkeley) 3/8/94
|
.\" @(#)fread.3 8.2 (Berkeley) 3/8/94
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 8, 1994
|
.Dd January 23, 2020
|
||||||
.Dt FREAD 3
|
.Dt FREAD 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm fread ,
|
.Nm fread ,
|
||||||
.Nm fwrite
|
.Nm fread_unlocked ,
|
||||||
|
.Nm fwrite ,
|
||||||
|
.Nm fwrite_unlocked
|
||||||
.Nd binary stream input/output
|
.Nd binary stream input/output
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
.Lb libc
|
.Lb libc
|
||||||
|
@ -46,7 +48,11 @@
|
||||||
.Ft size_t
|
.Ft size_t
|
||||||
.Fn fread "void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream"
|
.Fn fread "void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream"
|
||||||
.Ft size_t
|
.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"
|
.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
|
.Sh DESCRIPTION
|
||||||
The function
|
The function
|
||||||
.Fn fread
|
.Fn fread
|
||||||
|
@ -69,6 +75,21 @@ bytes long, to the stream pointed to by
|
||||||
.Fa stream ,
|
.Fa stream ,
|
||||||
obtaining them from the location given by
|
obtaining them from the location given by
|
||||||
.Fa ptr .
|
.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
|
.Sh RETURN VALUES
|
||||||
The functions
|
The functions
|
||||||
.Fn fread
|
.Fn fread
|
||||||
|
|
|
@ -115,3 +115,5 @@ __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
|
||||||
fp->_p += resid;
|
fp->_p += resid;
|
||||||
return (count);
|
return (count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__weak_reference(__fread, fread_unlocked);
|
||||||
|
|
|
@ -52,7 +52,8 @@ __FBSDID("$FreeBSD$");
|
||||||
* Return the number of whole objects written.
|
* Return the number of whole objects written.
|
||||||
*/
|
*/
|
||||||
size_t
|
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;
|
size_t n;
|
||||||
struct __suio uio;
|
struct __suio uio;
|
||||||
|
@ -84,7 +85,6 @@ fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict
|
||||||
uio.uio_iov = &iov;
|
uio.uio_iov = &iov;
|
||||||
uio.uio_iovcnt = 1;
|
uio.uio_iovcnt = 1;
|
||||||
|
|
||||||
FLOCKFILE_CANCELSAFE(fp);
|
|
||||||
ORIENT(fp, -1);
|
ORIENT(fp, -1);
|
||||||
/*
|
/*
|
||||||
* The usual case is success (__sfvwrite returns 0);
|
* The usual case is success (__sfvwrite returns 0);
|
||||||
|
@ -93,6 +93,17 @@ fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict
|
||||||
*/
|
*/
|
||||||
if (__sfvwrite(fp, &uio) != 0)
|
if (__sfvwrite(fp, &uio) != 0)
|
||||||
count = (n - uio.uio_resid) / size;
|
count = (n - uio.uio_resid) / size;
|
||||||
FUNLOCKFILE_CANCELSAFE();
|
|
||||||
return (count);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -32,11 +32,12 @@
|
||||||
.\" @(#)putc.3 8.1 (Berkeley) 6/4/93
|
.\" @(#)putc.3 8.1 (Berkeley) 6/4/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd January 10, 2003
|
.Dd January 23, 2020
|
||||||
.Dt PUTC 3
|
.Dt PUTC 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm fputc ,
|
.Nm fputc ,
|
||||||
|
.Nm fputc_unlocked ,
|
||||||
.Nm putc ,
|
.Nm putc ,
|
||||||
.Nm putc_unlocked ,
|
.Nm putc_unlocked ,
|
||||||
.Nm putchar ,
|
.Nm putchar ,
|
||||||
|
@ -50,6 +51,8 @@
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn fputc "int c" "FILE *stream"
|
.Fn fputc "int c" "FILE *stream"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn fputc_unlocked "int c" "FILE *stream"
|
||||||
|
.Ft int
|
||||||
.Fn putc "int c" "FILE *stream"
|
.Fn putc "int c" "FILE *stream"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn putc_unlocked "int c" "FILE *stream"
|
.Fn putc_unlocked "int c" "FILE *stream"
|
||||||
|
@ -97,11 +100,13 @@ to the named output
|
||||||
.Fa stream .
|
.Fa stream .
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Fn putc_unlocked
|
.Fn fputc_unlocked ,
|
||||||
|
.Fn putc_unlocked ,
|
||||||
and
|
and
|
||||||
.Fn putchar_unlocked
|
.Fn putchar_unlocked
|
||||||
functions are equivalent to
|
functions are equivalent to
|
||||||
.Fn putc
|
.Fn fputc ,
|
||||||
|
.Fn putc ,
|
||||||
and
|
and
|
||||||
.Fn putchar
|
.Fn putchar
|
||||||
respectively,
|
respectively,
|
||||||
|
|
Loading…
Reference in a new issue