stdio: Implement [clearerr|putc|fflush]_unlocked

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2023-10-22 03:59:06 +08:00 committed by Petro Karashchenko
parent 2c9511e655
commit f911d3a1c3
10 changed files with 129 additions and 22 deletions

View file

@ -1230,19 +1230,6 @@ int find_mtddriver(FAR const char *pathname, FAR struct inode **ppinode);
int close_mtddriver(FAR struct inode *pinode);
/****************************************************************************
* Name: lib_flushall
*
* Description:
* Called either (1) by the OS when a task exits, or (2) from fflush()
* when a NULL stream argument is provided.
*
****************************************************************************/
#ifdef CONFIG_FILE_STREAM
int lib_flushall(FAR struct streamlist *list);
#endif
/****************************************************************************
* Name: file_read
*

View file

@ -99,7 +99,6 @@
#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)
@ -140,8 +139,10 @@ extern "C"
/* Operations on streams (FILE) */
void clearerr(FAR FILE *stream);
void clearerr_unlocked(FAR FILE *stream);
int fclose(FAR FILE *stream);
int fflush(FAR FILE *stream);
int fflush_unlocked(FAR FILE *stream);
int feof(FAR FILE *stream);
int ferror(FAR FILE *stream);
int fileno(FAR FILE *stream);
@ -174,6 +175,7 @@ size_t fwrite(FAR const void *ptr, size_t size, size_t n_items,
size_t fwrite_unlocked(FAR const void *ptr, size_t size, size_t n_items,
FAR FILE *stream);
int getc(FAR FILE *stream);
int getc_unlocked(FAR FILE *stream);
int getchar(void);
int getchar_unlocked(void);
ssize_t getdelim(FAR char **lineptr, size_t *n, int delimiter,

View file

@ -162,6 +162,7 @@ size_t mbsrtowcs(FAR wchar_t *, FAR const char **, size_t,
wint_t putwc(wchar_t, FILE *);
wint_t putwc_unlocked(wchar_t, FAR FILE *);
wint_t putwchar(wchar_t);
wint_t putwchar_unlocked(wchar_t);
int swprintf(FAR wchar_t *, size_t, FAR const wchar_t *, ...);
int swscanf(FAR const wchar_t *, FAR const wchar_t *, ...);
wint_t ungetwc(wint_t, FILE *);

View file

@ -209,6 +209,13 @@ FAR char *lib_fgets(FAR char *buf, size_t buflen, FILE *stream,
FAR char *lib_fgets_unlocked(FAR char *buf, size_t buflen, FILE *stream,
bool keepnl, bool consume);
/* Defined in lib_flushall.c */
#ifdef CONFIG_FILE_STREAM
int lib_flushall(FAR struct streamlist *list);
int lib_flushall_unlocked(FAR struct streamlist *list);
#endif
/* Defined in lib_libfflush.c */
ssize_t lib_fflush(FAR FILE *stream);

View file

@ -46,8 +46,15 @@
*
****************************************************************************/
void clearerr(FAR FILE *stream)
void clearerr_unlocked(FAR FILE *stream)
{
stream->fs_flags &= (__FS_FLAG_LBF | __FS_FLAG_UBF);
}
void clearerr(FAR FILE *stream)
{
flockfile(stream);
clearerr_unlocked(stream);
funlockfile(stream);
}
#endif /* CONFIG_FILE_STREAM */

View file

@ -52,13 +52,48 @@
*
****************************************************************************/
int fflush_unlocked(FAR FILE *stream)
{
int ret;
/* Is the stream argument NULL? */
if (stream == NULL)
{
/* Yes... then this is a request to flush all streams */
ret = lib_flushall_unlocked(lib_get_streams());
}
else
{
ret = lib_fflush_unlocked(stream);
}
/* Check the return value */
if (ret < 0)
{
/* An error occurred during the flush AND/OR we were unable to flush
* all of the buffered write data. Set the errno value.
*/
set_errno(-ret);
/* And return EOF on failure. */
return EOF;
}
return OK;
}
int fflush(FAR FILE *stream)
{
int ret;
/* Is the stream argument NULL? */
if (!stream)
if (stream == NULL)
{
/* Yes... then this is a request to flush all streams */

View file

@ -64,7 +64,7 @@ wint_t fputwc_unlocked(wchar_t c, FAR FILE *f)
if (isascii(c))
{
c = putc(c, f);
c = putc_unlocked(c, f);
}
else
{

View file

@ -45,6 +45,54 @@
*
****************************************************************************/
int lib_flushall_unlocked(FAR struct streamlist *list)
{
int lasterrno = OK;
int ret;
/* Make sure that there are streams associated with this thread */
if (list != NULL)
{
FAR FILE *stream;
int i;
/* Process each stream in the thread's stream list */
for (i = 0; i < 3; i++)
{
lib_fflush_unlocked(&list->sl_std[i]);
}
for (stream = list->sl_head; stream != NULL; stream = stream->fs_next)
{
/* If the stream is opened for writing, then flush all of
* the pending write data in the stream.
*/
if ((stream->fs_oflags & O_WROK) != 0)
{
/* Flush the writable FILE */
ret = lib_fflush_unlocked(stream);
if (ret < 0)
{
/* An error occurred during the flush AND/OR we were unable
* to flush all of the buffered write data. Remember the
* last errcode.
*/
lasterrno = ret;
}
}
}
}
/* If any flush failed, return the errorcode of the last failed flush */
return lasterrno;
}
int lib_flushall(FAR struct streamlist *list)
{
int lasterrno = OK;
@ -52,7 +100,7 @@ int lib_flushall(FAR struct streamlist *list)
/* Make sure that there are streams associated with this thread */
if (list)
if (list != NULL)
{
FAR FILE *stream;
int i;
@ -66,8 +114,7 @@ int lib_flushall(FAR struct streamlist *list)
lib_fflush(&list->sl_std[i]);
}
stream = list->sl_head;
for (; stream != NULL; stream = stream->fs_next)
for (stream = list->sl_head; stream != NULL; stream = stream->fs_next)
{
/* If the stream is opened for writing, then flush all of
* the pending write data in the stream.

View file

@ -32,3 +32,8 @@ int putc(int c, FAR FILE *stream)
{
return fputc(c, stream);
}
int putc_unlocked(int c, FAR FILE *stream)
{
return fputc_unlocked(c, stream);
}

View file

@ -51,13 +51,14 @@
*
****************************************************************************/
wint_t putwchar(wchar_t c)
wint_t putwchar_unlocked(wchar_t c)
{
#ifdef CONFIG_FILE_STREAM
return fputwc(c, stdout);
return fputwc_unlocked(c, stdout);
#else
char mbc[MB_LEN_MAX];
int l;
l = wctomb(mbc, c);
if (l < 0)
{
@ -67,3 +68,18 @@ wint_t putwchar(wchar_t c)
return write(STDOUT_FILENO, mbc, l) == l ? c : WEOF;
#endif
}
wint_t putwchar(wchar_t c)
{
wint_t w;
#ifdef CONFIG_FILE_STREAM
flockfile(stdout);
#endif
w = putwchar_unlocked(c);
#ifdef CONFIG_FILE_STREAM
funlockfile(stdout);
#endif
return w;
}