OSDN Git Service

hidden_def/hidden_proto: convert all users (I hope) termios split, add some missing...
[uclinux-h8/uClibc.git] / libc / stdio / fclose.c
1 /* Copyright (C) 2004       Manuel Novoa III    <mjn3@codepoet.org>
2  *
3  * GNU Library General Public License (LGPL) version 2 or later.
4  *
5  * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details.
6  */
7
8 #define close __close
9
10 #include "_stdio.h"
11
12 libc_hidden_proto(close)
13 libc_hidden_proto(fflush_unlocked)
14
15 int fclose(register FILE *stream)
16 {
17         int rv = 0;
18         __STDIO_AUTO_THREADLOCK_VAR;
19
20         /* First, remove the file from the open file list. */
21 #ifdef __STDIO_HAS_OPENLIST
22         {
23                 register FILE *ptr;
24
25                 __STDIO_THREADLOCK_OPENLIST;
26                 if ((ptr = _stdio_openlist) == stream) {
27                         _stdio_openlist = stream->__nextopen;
28                 } else {
29                         while (ptr) {
30                                 if (ptr->__nextopen == stream) {
31                                         ptr->__nextopen = stream->__nextopen;
32                                         break;
33                                 }
34                                 ptr = ptr->__nextopen;
35                         }
36                 }
37                 __STDIO_THREADUNLOCK_OPENLIST;
38
39                 if (!ptr) {       /* Did not find stream in the open file list! */
40                         return EOF;
41                 }
42         }
43 #endif
44
45         __STDIO_AUTO_THREADLOCK(stream);
46
47         __STDIO_STREAM_VALIDATE(stream);
48
49 #ifdef __STDIO_BUFFERS
50         /* Write any pending buffered chars. */
51         if (__STDIO_STREAM_IS_WRITING(stream)) {
52                 rv = fflush_unlocked(stream);
53         }
54 #endif
55
56         if (__CLOSE(stream) < 0) {      /* Must close even if fflush failed. */
57                 rv = EOF;
58         }
59
60         stream->__filedes = -1;
61
62         /* We need a way for freopen to know that a file has been closed.
63          * Since a file can't be both readonly and writeonly, that makes
64          * an effective signal.  It also has the benefit of disabling
65          * transitions to either reading or writing. */
66         stream->__modeflags &= (__FLAG_FREEBUF|__FLAG_FREEFILE);
67         stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY);
68
69 #ifndef NDEBUG
70         __STDIO_STREAM_RESET_GCS(stream);
71
72         /* Reinitialize everything (including putc since fflush could fail). */
73         __STDIO_STREAM_DISABLE_GETC(stream);
74         __STDIO_STREAM_DISABLE_PUTC(stream);
75         __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);
76
77 # ifdef __UCLIBC_HAS_WCHAR__
78         stream->__ungot_width[0] = 0;
79 # endif
80 # ifdef __STDIO_MBSTATE
81         __INIT_MBSTATE(&(stream->__state));
82 # endif
83 #endif
84
85         __STDIO_AUTO_THREADUNLOCK(stream);
86
87         __STDIO_STREAM_FREE_BUFFER(stream);
88         __STDIO_STREAM_FREE_FILE(stream);
89
90         return rv;
91 }
92 libc_hidden_proto(fclose)
93 libc_hidden_def(fclose)