forked from nuttx/nuttx-update
Add support for freopen()
This commit is contained in:
parent
7c8bc43979
commit
006528b144
10 changed files with 226 additions and 81 deletions
|
@ -11138,3 +11138,5 @@
|
|||
* fs/vfs/open.c: If the use attempts to open a block driver, use
|
||||
block_proxy() to insert a character driver conversion layer in front
|
||||
of the block driver (2015-11-21).
|
||||
* libc/stdio/lib_freopen.c and include/stdio.h: Add support for
|
||||
freopen() (2015-11-22).
|
||||
|
|
|
@ -371,7 +371,7 @@ int pipecommon_close(FAR struct file *filep)
|
|||
}
|
||||
}
|
||||
|
||||
/* What is the buffer management policy? Do we free the buffe when the
|
||||
/* What is the buffer management policy? Do we free the buffer when the
|
||||
* last client closes the pipe policy 0, or when the buffer becomes empty.
|
||||
* In the latter case, the buffer data will remain valid and can be
|
||||
* obtained when the pipe is re-opened.
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
#include "driver/driver.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
#define F_GETSIG 6 /* Get the signal sent */
|
||||
#define F_NOTIFY 7 /* Provide notification when directory referred to by fd changes (linux)*/
|
||||
#define F_SETFD 8 /* Set the file descriptor flags to value */
|
||||
#define F_SETFL 9 /* Set the file status flags to the value */
|
||||
#define F_SETFL 9 /* Set the file status flags to the value */
|
||||
#define F_SETLEASE 10 /* Set or remove file lease (linux) */
|
||||
#define F_SETLK 11 /* Acquire or release a lock on range of bytes */
|
||||
#define F_SETLKW 12 /* Like F_SETLK, but wait for lock to become available */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* include/stdio.h
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -147,6 +147,7 @@ int fprintf(FAR FILE *stream, FAR const char *format, ...);
|
|||
int fputc(int c, FAR FILE *stream);
|
||||
int fputs(FAR const char *s, FAR FILE *stream);
|
||||
size_t fread(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);
|
||||
int fseek(FAR FILE *stream, long int offset, int whence);
|
||||
int fsetpos(FAR FILE *stream, FAR fpos_t *pos);
|
||||
long ftell(FAR FILE *stream);
|
||||
|
|
|
@ -155,7 +155,11 @@ char *__dtoa(double d, int mode, int ndigits, int *decpt, int *sign,
|
|||
char **rve);
|
||||
#endif
|
||||
|
||||
/* Defined in lib_libwrite.c */
|
||||
/* Defined in lib_fopen.c */
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -56,14 +56,15 @@ CSRCS += lib_rawsostream.c
|
|||
|
||||
ifneq ($(CONFIG_NFILE_STREAMS),0)
|
||||
|
||||
CSRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c
|
||||
CSRCS += lib_ftell.c lib_fsetpos.c lib_fgetpos.c lib_fgetc.c lib_fgets.c
|
||||
CSRCS += lib_gets_s.c lib_gets.c lib_libfgets.c lib_fwrite.c lib_libfwrite.c
|
||||
CSRCS += lib_fflush.c lib_libflushall.c lib_libfflush.c lib_rdflush.c
|
||||
CSRCS += lib_wrflush.c lib_fputc.c lib_puts.c lib_fputs.c lib_ungetc.c
|
||||
CSRCS += lib_vprintf.c lib_fprintf.c lib_vfprintf.c lib_stdinstream.c
|
||||
CSRCS += lib_stdoutstream.c lib_stdsistream.c lib_stdsostream.c lib_perror.c
|
||||
CSRCS += lib_feof.c lib_ferror.c lib_clearerr.c
|
||||
CSRCS += lib_fopen.c lib_freopen.c lib_fclose.c lib_fread.c lib_libfread.c
|
||||
CSRCS += lib_fseek.c lib_ftell.c lib_fsetpos.c lib_fgetpos.c lib_fgetc.c
|
||||
CSRCS += lib_fgets.c lib_gets_s.c lib_gets.c lib_libfgets.c lib_fwrite.c
|
||||
CSRCS += lib_libfwrite.c lib_fflush.c lib_libflushall.c lib_libfflush.c
|
||||
CSRCS += lib_rdflush.c lib_wrflush.c lib_fputc.c lib_puts.c lib_fputs.c
|
||||
CSRCS += lib_ungetc.c lib_vprintf.c lib_fprintf.c lib_vfprintf.c
|
||||
CSRCS += lib_stdinstream.c lib_stdoutstream.c lib_stdsistream.c
|
||||
CSRCS += lib_stdsostream.c lib_perror.c lib_feof.c lib_ferror.c
|
||||
CSRCS += lib_clearerr.c
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
int fileno(FAR FILE *stream)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (stream)
|
||||
{
|
||||
ret = stream->fs_fd;
|
||||
|
|
|
@ -69,18 +69,76 @@
|
|||
#define MODE_MASK (MODE_R | MODE_W | MODE_A)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
* Name: fdopen
|
||||
****************************************************************************/
|
||||
|
||||
FAR FILE *fdopen(int fd, FAR const char *mode)
|
||||
{
|
||||
FAR FILE *ret = NULL;
|
||||
int oflags;
|
||||
|
||||
/* Map the open mode string to open flags */
|
||||
|
||||
oflags = lib_mode2oflags(mode);
|
||||
if (oflags >= 0)
|
||||
{
|
||||
ret = fs_fdopen(fd, oflags, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fopen
|
||||
****************************************************************************/
|
||||
|
||||
FAR FILE *fopen(FAR const char *path, FAR const char *mode)
|
||||
{
|
||||
FAR FILE *ret = NULL;
|
||||
int oflags;
|
||||
int fd;
|
||||
|
||||
/* Map the open mode string to open flags */
|
||||
|
||||
oflags = lib_mode2oflags(mode);
|
||||
if (oflags < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Open the file */
|
||||
|
||||
fd = open(path, oflags, 0666);
|
||||
|
||||
/* If the open was successful, then fdopen() the fil using the file
|
||||
* descriptor returned by open. If open failed, then just return the
|
||||
* NULL stream -- open() has already set the errno.
|
||||
*/
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
ret = fs_fdopen(fd, oflags, NULL);
|
||||
if (!ret)
|
||||
{
|
||||
/* Don't forget to close the file descriptor if any other
|
||||
* failures are reported by fdopen().
|
||||
*/
|
||||
|
||||
(void)close(fd);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lib_mode2oflags
|
||||
****************************************************************************/
|
||||
|
||||
static int lib_mode2oflags(FAR const char *mode)
|
||||
int lib_mode2oflags(FAR const char *mode)
|
||||
{
|
||||
unsigned int state;
|
||||
int oflags;
|
||||
|
@ -246,69 +304,3 @@ errout:
|
|||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fdopen
|
||||
****************************************************************************/
|
||||
|
||||
FAR FILE *fdopen(int fd, FAR const char *mode)
|
||||
{
|
||||
FAR FILE *ret = NULL;
|
||||
int oflags;
|
||||
|
||||
/* Map the open mode string to open flags */
|
||||
|
||||
oflags = lib_mode2oflags(mode);
|
||||
if (oflags >= 0)
|
||||
{
|
||||
ret = fs_fdopen(fd, oflags, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fopen
|
||||
****************************************************************************/
|
||||
|
||||
FAR FILE *fopen(FAR const char *path, FAR const char *mode)
|
||||
{
|
||||
FAR FILE *ret = NULL;
|
||||
int oflags;
|
||||
int fd;
|
||||
|
||||
/* Map the open mode string to open flags */
|
||||
|
||||
oflags = lib_mode2oflags(mode);
|
||||
if (oflags < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Open the file */
|
||||
|
||||
fd = open(path, oflags, 0666);
|
||||
|
||||
/* If the open was successful, then fdopen() the fil using the file
|
||||
* descriptor returned by open. If open failed, then just return the
|
||||
* NULL stream -- open() has already set the errno.
|
||||
*/
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
ret = fs_fdopen(fd, oflags, NULL);
|
||||
if (!ret)
|
||||
{
|
||||
/* Don't forget to close the file descriptor if any other
|
||||
* failures are reported by fdopen().
|
||||
*/
|
||||
|
||||
(void)close(fd);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
143
libc/stdio/lib_freopen.c
Normal file
143
libc/stdio/lib_freopen.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/****************************************************************************
|
||||
* libc/stdio/lib_freopen.c
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "lib_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: freopen
|
||||
*
|
||||
* Description:
|
||||
* Reuses stream to either open the file specified by path or to change
|
||||
* its access mode.
|
||||
*
|
||||
* If a new path is specified, the function first attempts to close
|
||||
* any file already associated with stream (third parameter) and
|
||||
* disassociates it. Then, independently of whether that stream was
|
||||
* successfuly closed or not, freopen opens the file specified by path
|
||||
* and associates it with the stream just as fopen would do using the
|
||||
* specified mode.
|
||||
*
|
||||
* If path is a null pointer, the function attempts to change the mode
|
||||
* of the stream. Although a particular library implementation is allowed
|
||||
* to restrict the changes permitted, and under which circumstances.
|
||||
*
|
||||
* The error indicator and eof indicator are automatically cleared (as if
|
||||
* clearerr was called).
|
||||
*
|
||||
* Input Paramters:
|
||||
* path - If non-NULL, refers to the name of the file to be opened.
|
||||
* mode - String describing the new file access mode
|
||||
* stream - Pointer to the type FILE to be reopened.
|
||||
*
|
||||
* Returned Value:
|
||||
* If the file is successfully reopened, the function returns the pointer
|
||||
* passed as parameter stream, which can be used to identify the reopened
|
||||
* stream. Otherwise, a null pointer is returned and the errno variable
|
||||
* is also set to a system-specific error code on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR FILE *freopen(FAR const char *path, FAR const char *mode,
|
||||
FAR FILE *stream)
|
||||
{
|
||||
int oflags;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
/* Was a file name provided? */
|
||||
|
||||
if (path != NULL)
|
||||
{
|
||||
/* Yes, close the stream */
|
||||
|
||||
if (stream)
|
||||
{
|
||||
(void)fclose(stream);
|
||||
}
|
||||
|
||||
/* And attempt to reopen the file at the provided path */
|
||||
|
||||
return fopen(path, mode);
|
||||
}
|
||||
|
||||
/* Otherwise, we are just changing the mode of the current file. */
|
||||
|
||||
if (stream)
|
||||
{
|
||||
/* Convert the mode string into standard file open mode flags. */
|
||||
|
||||
oflags = lib_mode2oflags(mode);
|
||||
if (oflags == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the underlying file descriptor from the stream */
|
||||
|
||||
fd = fileno(stream);
|
||||
if (fd < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the new file mode for the file descriptor */
|
||||
|
||||
ret = fcntl(fd, F_SETFL, oflags);
|
||||
if (ret < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clearerr(stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
set_errno(EINVAL);
|
||||
return NULL;
|
||||
}
|
Loading…
Reference in a new issue