Initial revision
[karo-tx-redboot.git] / packages / language / c / libc / stdio / v2_0 / src / common / fclose.cxx
1 //===========================================================================
2 //
3 //      fclose.cxx
4 //
5 //      Implementation of C library file close function as per ANSI 7.9.5.1
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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####
42 //
43 // Author(s):     jlarmour
44 // Contributors:  
45 // Date:          2000-04-20
46 // Purpose:       Implements ISO C fclose() function
47 // Description: 
48 // Usage:       
49 //
50 //####DESCRIPTIONEND####
51 //
52 //===========================================================================
53
54 // CONFIGURATION
55
56 #include <pkgconf/libc_stdio.h>   // Configuration header
57 #include <pkgconf/infra.h>
58
59 // INCLUDES
60
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 fclose()
65 #include <stdlib.h>                 // free()
66 #include <cyg/libc/stdio/stdiofiles.hxx>  // C library files
67 #include <cyg/libc/stdio/stream.hxx>      // C library streams
68
69 #include <cyg/libc/stdio/io.inl>     // I/O system inlines
70
71 // FUNCTIONS
72
73
74 externC int
75 fclose( FILE *stream ) __THROW
76 {
77     Cyg_StdioStream *real_stream = (Cyg_StdioStream *)stream;
78     int i;
79     Cyg_ErrNo err;
80
81     if (NULL == real_stream)
82     {
83         errno = EBADF;
84         return EOF;
85     }
86
87     Cyg_libc_stdio_files::lock();
88
89     // find the stream in the table
90     for (i=0; i < FOPEN_MAX; i++)
91     {
92         if (real_stream == Cyg_libc_stdio_files::get_file_stream(i))
93             break;
94     } // for
95
96     if (i == FOPEN_MAX) // didn't find it
97     {
98         Cyg_libc_stdio_files::unlock();
99         errno = EBADF;
100         return EOF;
101     } // if
102
103     err = real_stream->close();
104
105     if( err != ENOERR )
106     {
107         Cyg_libc_stdio_files::unlock();
108         errno = err;
109         return EOF;
110     }
111     
112 #ifdef CYGFUN_INFRA_EMPTY_DELETE_FUNCTIONS
113     // Explicitly call destructor - this flushes the output too
114     real_stream->~Cyg_StdioStream();
115
116     // and free it
117     free(real_stream);
118 #else
119     delete real_stream;
120 #endif // CYGFUN_INFRA_EMPTY_DELETE_FUNCTIONS
121
122     // and mark the stream available for use
123     Cyg_libc_stdio_files::set_file_stream(i, NULL);
124         
125     Cyg_libc_stdio_files::unlock();
126
127     return 0;
128
129 } // fclose()
130         
131 // EOF fclose.cxx