1 //===========================================================================
5 // Implementation of C library file open function as per ANSI 7.9.5.3
7 //===========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //===========================================================================
41 //#####DESCRIPTIONBEGIN####
43 // Author(s): jlarmour
46 // Purpose: Implements ISO C fopen() function
50 //####DESCRIPTIONEND####
52 //===========================================================================
56 #include <pkgconf/libc_stdio.h> // Configuration header
61 #include <cyg/infra/cyg_type.h> // Common project-wide type definitions
62 #include <stddef.h> // NULL and size_t from compiler
63 #include <errno.h> // Error codes
64 #include <stdio.h> // header for fopen()
65 #include <stdlib.h> // malloc()
66 #include <string.h> // strncmp() and strcmp()
67 #include <cyg/libc/stdio/stdiofiles.hxx> // C library files
68 #include <cyg/libc/stdio/stream.hxx> // C library streams
70 #include <cyg/libc/stdio/io.inl> // I/O system inlines
75 inline void *operator new(size_t size, void *ptr)
77 CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );
81 // process the mode string. Return true on error
83 process_mode( const char *mode, Cyg_StdioStream::OpenMode *rw,
84 cyg_bool *binary, cyg_bool *append )
86 *binary = *append = false; // default
90 *rw = Cyg_StdioStream::CYG_STREAM_READ;
96 *rw = Cyg_StdioStream::CYG_STREAM_WRITE;
103 // ANSI says additional characters may follow the sequences, that we
104 // don't necessarily recognise so we just ignore them, and pretend that
105 // its the end of the string
113 *rw = Cyg_StdioStream::CYG_STREAM_READWRITE_NOCREATE;
115 *rw = Cyg_StdioStream::CYG_STREAM_READWRITE_CREATE;
127 *rw = Cyg_StdioStream::CYG_STREAM_READWRITE_NOCREATE;
129 *rw = Cyg_StdioStream::CYG_STREAM_READWRITE_CREATE;
139 static FILE *fopen_inner( cyg_stdio_handle_t dev,
140 Cyg_StdioStream::OpenMode open_mode,
144 Cyg_StdioStream *curr_stream;
147 int bufmode = _IOFBF;
148 cyg_ucount32 bufsize = BUFSIZ;
150 Cyg_libc_stdio_files::lock();
152 // find an empty slot
153 for (i=0; i < FOPEN_MAX; i++) {
154 curr_stream = Cyg_libc_stdio_files::get_file_stream(i);
155 if (curr_stream == NULL)
159 if (i == FOPEN_MAX) { // didn't find an empty slot
161 cyg_stdio_close( dev );
162 Cyg_libc_stdio_files::unlock();
166 // Decide the buffering mode. The default is fully buffered, but if
167 // this is an interactive stream then set it to non buffered.
168 if( (dev != CYG_STDIO_HANDLE_NULL) &&
169 cyg_stdio_interactive( dev ) )
170 bufmode = _IONBF, bufsize = 0;
172 // Allocate it some memory and construct it.
173 curr_stream = (Cyg_StdioStream *)malloc(sizeof(*curr_stream));
174 if (curr_stream == NULL) {
175 cyg_stdio_close( dev );
176 Cyg_libc_stdio_files::unlock();
181 curr_stream = new ((void *)curr_stream) Cyg_StdioStream( dev, open_mode,
184 // it puts any error in its own error flag
185 if (( err=curr_stream->get_error() )) {
187 Cyg_libc_stdio_files::unlock();
191 cyg_stdio_close( dev );
199 Cyg_libc_stdio_files::set_file_stream(i, curr_stream);
201 Cyg_libc_stdio_files::unlock();
203 return (FILE *)(curr_stream);
208 fopen( const char *filename, const char *mode ) __THROW
210 cyg_stdio_handle_t dev = 0;
212 Cyg_StdioStream::OpenMode open_mode = Cyg_StdioStream::CYG_STREAM_READ;
213 cyg_bool binary, append;
215 // process_mode returns true on error
216 if (process_mode( mode, &open_mode, &binary, &append )) {
221 err = cyg_stdio_open( filename, open_mode, binary, append, &dev );
229 return fopen_inner( dev, open_mode, binary, append );
234 #ifdef CYGFUN_LIBC_STDIO_OPEN_POSIX_FDFUNCS
236 externC int fileno( FILE *stream ) __THROW
238 Cyg_StdioStream *real_stream = (Cyg_StdioStream *)stream;
240 return real_stream->get_dev();
243 externC FILE *fdopen( int fd, const char *mode ) __THROW
245 Cyg_StdioStream::OpenMode open_mode;
246 cyg_bool binary, append;
249 // process_mode returns true on error
250 if (process_mode( mode, &open_mode, &binary, &append )) {
255 f = fopen_inner( (cyg_stdio_handle_t)fd, open_mode, binary, append );
260 // Do a null seek to initialize the file position.
261 Cyg_StdioStream *real_stream = (Cyg_StdioStream *)f;
263 real_stream->set_position( pos, SEEK_CUR );
267 #endif // def CYGFUN_LIBC_STDIO_OPEN_POSIX_FDFUNCS