stdio: Implement [clearerr|putc|fflush]_unlocked
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
parent
2c9511e655
commit
f911d3a1c3
10 changed files with 129 additions and 22 deletions
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue