libs/libc: support unlock version for fread/fwrite/fputc/fgetc/...

Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
dongjiuzhu1 2023-08-30 15:40:39 +08:00 committed by Petro Karashchenko
parent e8842f59da
commit df98320c2c
18 changed files with 183 additions and 57 deletions

View File

@ -99,6 +99,11 @@
#define setlinebuf(stream) setvbuf(stream, NULL, _IOLBF, 0)
#define clearerr_unlocked(stream) clearerr(stream)
#define feof_unlocked(stream) feof(stream)
#define ferror_unlocked(stream) ferror(stream)
#define fileno_unlocked(stream) fileno(stream)
/****************************************************************************
* Public Type Definitions
****************************************************************************/
@ -141,16 +146,22 @@ int feof(FAR FILE *stream);
int ferror(FAR FILE *stream);
int fileno(FAR FILE *stream);
int fgetc(FAR FILE *stream);
int fgetc_unlocked(FAR FILE *stream);
int fgetpos(FAR FILE *stream, FAR fpos_t *pos);
FAR char *fgets(FAR char *s, int n, FAR FILE *stream);
FAR char *fgets_unlocked(FAR char *s, int n, FAR FILE *stream);
FAR FILE *fopen(FAR const char *path, FAR const char *type) fopen_like;
int fprintf(FAR FILE *stream, FAR const IPTR char *format, ...)
printf_like(2, 3);
int fputc(int c, FAR FILE *stream);
int fputc_unlocked(int c, FAR FILE *stream);
int fputs(FAR const IPTR char *s, FAR FILE *stream);
int fputs_unlocked(FAR const IPTR char *s, FAR FILE *stream);
size_t fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream);
size_t fread_unlocked(FAR void *ptr, size_t size, size_t n_items,
FAR FILE *stream);
FAR FILE *freopen(FAR const char *path, FAR const char *mode,
FAR FILE *stream);
FAR FILE *stream);
int fscanf(FAR FILE *stream, FAR const IPTR char *fmt, ...)
scanf_like(2, 3);
int fseek(FAR FILE *stream, long int offset, int whence);
@ -159,11 +170,14 @@ int fsetpos(FAR FILE *stream, FAR fpos_t *pos);
long ftell(FAR FILE *stream);
off_t ftello(FAR FILE *stream);
size_t fwrite(FAR const void *ptr, size_t size, size_t n_items,
FAR FILE *stream);
FAR FILE *stream);
size_t fwrite_unlocked(FAR const void *ptr, size_t size, size_t n_items,
FAR FILE *stream);
int getc(FAR FILE *stream);
int getchar(void);
int getchar_unlocked(void);
ssize_t getdelim(FAR char **lineptr, size_t *n, int delimiter,
FAR FILE *stream);
FAR FILE *stream);
ssize_t getline(FAR char **lineptr, size_t *n, FAR FILE *stream);
FAR char *gets(FAR char *s);
FAR char *gets_s(FAR char *s, rsize_t n);
@ -186,7 +200,9 @@ void funlockfile(FAR FILE *stream);
void perror(FAR const char *s);
int printf(FAR const IPTR char *fmt, ...) printf_like(1, 2);
int putc(int c, FAR FILE *stream);
int putc_unlocked(int c, FAR FILE *stream);
int putchar(int c);
int putchar_unlocked(int c);
int puts(FAR const IPTR char *s);
int rename(FAR const char *oldpath, FAR const char *newpath);
int renameat(int olddirfd, FAR const char *oldpath,
@ -196,7 +212,7 @@ int sprintf(FAR char *buf, FAR const IPTR char *fmt, ...)
int asprintf(FAR char **ptr, FAR const IPTR char *fmt, ...)
printf_like(2, 3);
int snprintf(FAR char *buf, size_t size,
FAR const IPTR char *fmt, ...) printf_like(3, 4);
FAR const IPTR char *fmt, ...) printf_like(3, 4);
int sscanf(FAR const char *buf, FAR const IPTR char *fmt, ...)
scanf_like(2, 3);
@ -204,13 +220,13 @@ int scanf(FAR const IPTR char *fmt, ...) scanf_like(1, 2);
int vasprintf(FAR char **ptr, FAR const IPTR char *fmt, va_list ap)
printf_like(2, 0);
int vfprintf(FAR FILE *stream, FAR const IPTR char *fmt,
va_list ap) printf_like(2, 0);
va_list ap) printf_like(2, 0);
int vfscanf(FAR FILE *stream, FAR const IPTR char *fmt, va_list ap)
scanf_like(2, 0);
int vprintf(FAR const IPTR char *fmt, va_list ap) printf_like(1, 0);
int vscanf(FAR const IPTR char *fmt, va_list ap) scanf_like(1, 0);
int vsnprintf(FAR char *buf, size_t size, FAR const IPTR char *fmt,
va_list ap) printf_like(3, 0);
va_list ap) printf_like(3, 0);
int vsprintf(FAR char *buf, FAR const IPTR char *fmt, va_list ap)
printf_like(2, 0);
int vsscanf(FAR const char *buf, FAR const IPTR char *fmt, va_list ap)

View File

@ -217,10 +217,12 @@ int lib_mode2oflags(FAR const char *mode);
/* Defined in lib_libfwrite.c */
ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream);
ssize_t lib_fwrite_unlocked(FAR const void *ptr, size_t count,
FAR FILE *stream);
/* Defined in lib_libfread.c */
/* Defined in lib_libfread_unlocked.c */
ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream);
ssize_t lib_fread_unlocked(FAR void *ptr, size_t count, FAR FILE *stream);
/* Defined in lib_libgets.c */
@ -231,6 +233,8 @@ FAR char *lib_dgets(FAR char *buf, size_t buflen, int fd,
FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream,
bool keepnl, bool consume);
FAR char *lib_fgets_unlocked(FAR char *buf, size_t buflen, FILE *stream,
bool keepnl, bool consume);
/* Defined in lib_libfflush.c */

View File

@ -60,7 +60,7 @@ if(CONFIG_FILE_STREAM)
lib_freopen.c
lib_fclose.c
lib_fread.c
lib_libfread.c
lib_libfread_unlocked.c
lib_fseek.c
lib_fseeko.c
lib_ftell.c

View File

@ -37,7 +37,7 @@ endif
# The remaining sources files depend upon C streams
ifeq ($(CONFIG_FILE_STREAM),y)
CSRCS += lib_fopen.c lib_freopen.c lib_fclose.c lib_fread.c lib_libfread.c
CSRCS += lib_fopen.c lib_freopen.c lib_fclose.c lib_fread.c lib_libfread_unlocked.c
CSRCS += lib_fseek.c lib_fseeko.c lib_ftell.c lib_ftello.c lib_fsetpos.c
CSRCS += lib_getdelim.c lib_fgetpos.c lib_getc.c lib_fgetc.c
CSRCS += lib_fgets.c lib_libfgets.c lib_fwrite.c

View File

@ -33,12 +33,12 @@
* fgetc
****************************************************************************/
int fgetc(FAR FILE *stream)
int fgetc_unlocked(FAR FILE *stream)
{
unsigned char ch;
ssize_t ret;
ret = lib_fread(&ch, 1, stream);
ret = lib_fread_unlocked(&ch, 1, stream);
if (ret > 0)
{
return ch;
@ -48,3 +48,14 @@ int fgetc(FAR FILE *stream)
return EOF;
}
}
int fgetc(FAR FILE *stream)
{
int ret;
flockfile(stream);
ret = fgetc_unlocked(stream);
funlockfile(stream);
return ret;
}

View File

@ -44,7 +44,7 @@
*
****************************************************************************/
char *fgets(FAR char *buf, int buflen, FAR FILE *stream)
FAR char *fgets_unlocked(FAR char *buf, int buflen, FAR FILE *stream)
{
/* Handle negative buffer size */
@ -57,6 +57,17 @@ char *fgets(FAR char *buf, int buflen, FAR FILE *stream)
else
{
return lib_fgets(buf, buflen, stream, true, false);
return lib_fgets_unlocked(buf, buflen, stream, true, false);
}
}
FAR char *fgets(FAR char *buf, int buflen, FAR FILE *stream)
{
FAR char *ret;
flockfile(stream);
ret = fgets_unlocked(buf, buflen, stream);
funlockfile(stream);
return ret;
}

View File

@ -33,19 +33,19 @@
* Name: fputc
****************************************************************************/
int fputc(int c, FAR FILE *stream)
int fputc_unlocked(int c, FAR FILE *stream)
{
unsigned char buf = (unsigned char)c;
int ret;
ret = lib_fwrite(&buf, 1, stream);
ret = lib_fwrite_unlocked(&buf, 1, stream);
if (ret > 0)
{
/* Flush the buffer if a newline is output */
if (c == '\n' && (stream->fs_flags & __FS_FLAG_LBF) != 0)
{
ret = lib_fflush(stream, true);
ret = lib_fflush_unlocked(stream, true);
if (ret < 0)
{
return EOF;
@ -59,3 +59,14 @@ int fputc(int c, FAR FILE *stream)
return EOF;
}
}
int fputc(int c, FAR FILE *stream)
{
int ret;
flockfile(stream);
ret = fputc_unlocked(c, stream);
funlockfile(stream);
return ret;
}

View File

@ -45,7 +45,7 @@
****************************************************************************/
#if defined(CONFIG_ARCH_ROMGETC)
int fputs(FAR const IPTR char *s, FAR FILE *stream)
int fputs_unlocked(FAR const IPTR char *s, FAR FILE *stream)
{
int nput;
int ret;
@ -57,7 +57,7 @@ int fputs(FAR const IPTR char *s, FAR FILE *stream)
{
/* Write the next character to the stream buffer */
ret = lib_fwrite(&ch, 1, stream);
ret = lib_fwrite_unlocked(&ch, 1, stream);
if (ret <= 0)
{
return EOF;
@ -67,7 +67,7 @@ int fputs(FAR const IPTR char *s, FAR FILE *stream)
if (ch == '\n' && (stream->fs_flags & __FS_FLAG_LBF) != 0)
{
ret = lib_fflush(stream, true);
ret = lib_fflush_unlocked(stream, true);
if (ret < 0)
{
return EOF;
@ -79,7 +79,7 @@ int fputs(FAR const IPTR char *s, FAR FILE *stream)
}
#else
int fputs(FAR const IPTR char *s, FAR FILE *stream)
int fputs_unlocked(FAR const IPTR char *s, FAR FILE *stream)
{
int nput;
@ -97,7 +97,7 @@ int fputs(FAR const IPTR char *s, FAR FILE *stream)
{
/* Write the next character to the stream buffer */
ret = lib_fwrite(s, 1, stream);
ret = lib_fwrite_unlocked(s, 1, stream);
if (ret <= 0)
{
return EOF;
@ -107,7 +107,7 @@ int fputs(FAR const IPTR char *s, FAR FILE *stream)
if (*s == '\n')
{
ret = lib_fflush(stream, true);
ret = lib_fflush_unlocked(stream, true);
if (ret < 0)
{
return EOF;
@ -132,7 +132,7 @@ int fputs(FAR const IPTR char *s, FAR FILE *stream)
/* Write the string */
nput = lib_fwrite(s, ntowrite, stream);
nput = lib_fwrite_unlocked(s, ntowrite, stream);
if (nput < 0)
{
return EOF;
@ -142,3 +142,14 @@ int fputs(FAR const IPTR char *s, FAR FILE *stream)
return nput;
}
#endif
int fputs(FAR const IPTR char *s, FAR FILE *stream)
{
int ret;
flockfile(stream);
ret = fputs_unlocked(s, stream);
funlockfile(stream);
return ret;
}

View File

@ -37,7 +37,8 @@
* Name: fread
****************************************************************************/
size_t fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream)
size_t fread_unlocked(FAR void *ptr, size_t size,
size_t n_items, FAR FILE *stream)
{
size_t full_size = n_items * (size_t)size;
ssize_t bytes_read;
@ -45,7 +46,7 @@ size_t fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream)
/* Write the data into the stream buffer */
bytes_read = lib_fread(ptr, full_size, stream);
bytes_read = lib_fread_unlocked(ptr, full_size, stream);
if (bytes_read > 0)
{
/* Return the number of full items read */
@ -55,3 +56,15 @@ size_t fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream)
return items_read;
}
size_t fread(FAR void *ptr, size_t size, size_t n_items, FAR FILE *stream)
{
size_t ret;
flockfile(stream);
ret = fread_unlocked(ptr, size, n_items, stream);
funlockfile(stream);
return ret;
}

View File

@ -37,8 +37,8 @@
* Name: fwrite
****************************************************************************/
size_t fwrite(FAR const void *ptr, size_t size, size_t n_items,
FAR FILE *stream)
size_t fwrite_unlocked(FAR const void *ptr, size_t size, size_t n_items,
FAR FILE *stream)
{
size_t full_size = n_items * (size_t)size;
ssize_t bytes_written;
@ -46,7 +46,7 @@ size_t fwrite(FAR const void *ptr, size_t size, size_t n_items,
/* Write the data into the stream buffer */
bytes_written = lib_fwrite(ptr, full_size, stream);
bytes_written = lib_fwrite_unlocked(ptr, full_size, stream);
if (bytes_written > 0)
{
/* Return the number of full items written */
@ -56,3 +56,16 @@ size_t fwrite(FAR const void *ptr, size_t size, size_t n_items,
return items_written;
}
size_t fwrite(FAR const void *ptr, size_t size, size_t n_items,
FAR FILE *stream)
{
size_t ret;
flockfile(stream);
ret = fwrite_unlocked(ptr, size, n_items, stream);
funlockfile(stream);
return ret;
}

View File

@ -32,3 +32,8 @@ int getc(FAR FILE *stream)
{
return fgetc(stream);
}
int getc_unlocked(FAR FILE *stream)
{
return fgetc_unlocked(stream);
}

View File

@ -38,3 +38,13 @@ int getchar(void)
return read(STDIN_FILENO, &c, 1) == 1 ? c : EOF;
#endif
}
int getchar_unlocked(void)
{
#ifdef CONFIG_FILE_STREAM
return fgetc_unlocked(stdin);
#else
unsigned char c;
return read(STDIN_FILENO, &c, 1) == 1 ? c : EOF;
#endif
}

View File

@ -60,7 +60,7 @@ static void consume_eol(FILE *stream, bool consume)
do
{
ch = fgetc(stream);
ch = fgetc_unlocked(stream);
}
while (ch != EOF && ch != '\n');
}
@ -93,8 +93,8 @@ static void consume_eol(FILE *stream, bool consume)
*
****************************************************************************/
FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream,
bool keepnl, bool consume)
FAR char *lib_fgets_unlocked(FAR char *buf, size_t buflen, FILE *stream,
bool keepnl, bool consume)
{
size_t nch = 0;
@ -133,7 +133,7 @@ FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream,
{
/* Get the next character */
int ch = fgetc(stream);
int ch = fgetc_unlocked(stream);
/* Check for end-of-line. This is tricky only in that some
* environments may return CR as end-of-line, others LF, and
@ -203,3 +203,15 @@ FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream,
}
}
}
FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream,
bool keepnl, bool consume)
{
FAR char *ret;
flockfile(stream);
ret = lib_fgets_unlocked(buf, buflen, stream, keepnl, consume);
funlockfile(stream);
return ret;
}

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libs/libc/stdio/lib_libfread.c
* libs/libc/stdio/lib_libfread_unlocked.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@ -41,10 +41,10 @@
****************************************************************************/
/****************************************************************************
* Name: lib_fread
* Name: lib_fread_unlocked
****************************************************************************/
ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream)
ssize_t lib_fread_unlocked(FAR void *ptr, size_t count, FAR FILE *stream)
{
FAR unsigned char *dest = (FAR unsigned char *)ptr;
ssize_t bytes_read;
@ -69,10 +69,6 @@ ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream)
}
else
{
/* The stream must be stable until we complete the read */
flockfile(stream);
#if CONFIG_NUNGET_CHARS > 0
/* First, re-read any previously ungotten characters */
@ -102,7 +98,7 @@ ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream)
* concurrent buffered read/write access.
*/
ret = lib_wrflush(stream);
ret = lib_wrflush_unlocked(stream);
if (ret < 0)
{
if (count - remaining > 0)
@ -318,7 +314,6 @@ shortread:
stream->fs_flags |= __FS_FLAG_EOF;
}
funlockfile(stream);
return count - remaining;
}
@ -326,6 +321,5 @@ shortread:
errout_with_errno:
stream->fs_flags |= __FS_FLAG_ERROR;
funlockfile(stream);
return ERROR;
}

View File

@ -43,7 +43,8 @@
* Name: lib_fwrite
****************************************************************************/
ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
ssize_t lib_fwrite_unlocked(FAR const void *ptr, size_t count,
FAR FILE *stream)
#ifndef CONFIG_STDIO_DISABLE_BUFFERING
{
FAR const unsigned char *start = ptr;
@ -81,10 +82,6 @@ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
goto errout;
}
/* Get exclusive access to the stream */
flockfile(stream);
/* If the buffer is currently being used for read access, then
* discard all of the read-ahead data. We do not support concurrent
* buffered read/write access.
@ -92,7 +89,7 @@ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
if (lib_rdflush_unlocked(stream) < 0)
{
goto errout_with_lock;
goto errout;
}
/* Determine the number of bytes left in the buffer */
@ -128,7 +125,7 @@ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
int bytes_buffered = lib_fflush_unlocked(stream, false);
if (bytes_buffered < 0)
{
goto errout_with_lock;
goto errout;
}
}
}
@ -140,7 +137,7 @@ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
{
_NX_SETERRNO(ret);
ret = ERROR;
goto errout_with_lock;
goto errout;
}
src += ret;
@ -156,9 +153,6 @@ ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
ret = (uintptr_t)src - (uintptr_t)start;
errout_with_lock:
funlockfile(stream);
errout:
if (ret < 0)
{
@ -179,3 +173,14 @@ errout:
return ret;
}
#endif /* CONFIG_STDIO_DISABLE_BUFFERING */
ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
{
ssize_t ret;
flockfile(stream);
ret = lib_fwrite_unlocked(ptr, count, stream);
funlockfile(stream);
return ret;
}

View File

@ -38,3 +38,13 @@ int putchar(int c)
return write(STDOUT_FILENO, &tmp, 1) == 1 ? c : EOF;
#endif
}
int putchar_unlocked(int c)
{
#ifdef CONFIG_FILE_STREAM
return fputc_unlocked(c, stdout);
#else
unsigned char tmp = c;
return write(STDOUT_FILENO, &tmp, 1) == 1 ? c : EOF;
#endif
}

View File

@ -54,13 +54,13 @@ int puts(FAR const IPTR char *s)
/* Write the string without its trailing '\0' */
nwritten = fputs(s, stream);
nwritten = fputs_unlocked(s, stream);
if (nwritten > 0)
{
/* Followed by a newline */
char newline = '\n';
ret = lib_fwrite(&newline, 1, stream);
ret = lib_fwrite_unlocked(&newline, 1, stream);
if (ret > 0)
{
nput = nwritten + 1;

View File

@ -92,7 +92,7 @@ int lib_rdflush_unlocked(FAR FILE *stream)
* user
*/
if (fseek(stream, -rdoffset, SEEK_CUR) < 0)
if (lseek(stream->fs_fd, -rdoffset, SEEK_CUR) < 0)
{
return ERROR;
}