1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
/***
*fclose.c - close a file
*
* Copyright (c) 1985-1993, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines fclose() - close an open file
*
*Revision History:
* 09-02-83 RN initial version
* 05-14-87 SKS error return from fflush must not be clobbered
* 08-10-87 JCR Added code to support P_tmpdir with or without trailing '\'
* 11-01-87 JCR Multi-thread support
* 12-11-87 JCR Added "_LOAD_DS" to declaration
* 01-13-88 JCR Removed unnecessary calls to mthread fileno/feof/ferror
* 05-31-88 PHG Merged DLL and normal versions
* 06-14-88 JCR Use near pointer to reference _iob[] entries
* 08-24-88 GJF Don't use FP_OFF() macro for the 386
* 08-17-89 GJF Clean up, now specific to OS/2 2.0 (i.e., 386 flat
* model). Also fixed copyright and indents.
* 02-15-90 GJF Fixed copyright
* 03-16-90 GJF Made calling type _CALLTYPE1, added #include
* <cruntime.h> and removed #include <register.h>.
* 05-29-90 SBM Use _flush, not [_]fflush[_lk]
* 07-25-90 SBM Replaced <assertm.h> by <assert.h>
* 10-02-90 GJF New-style function declarator.
* 01-21-91 GJF ANSI naming.
* 03-11-92 GJF For Win32, revised temporary file cleanup.
* 03-25-92 DJM POSIX support.
* 08-26-92 GJF Include unistd.h for POSIX build.
* 01-13-93 GJF Don't need/want to remove() tmp files on Windows NT
* (file is removed by the OS when handle is closed).
*
*******************************************************************************/
#include <cruntime.h>
#ifdef _POSIX_
#include <unistd.h>
#endif
#include <stdio.h>
#include <file2.h>
#include <assert.h>
#include <string.h>
#include <io.h>
#include <stdlib.h>
#include <internal.h>
#include <os2dll.h>
/***
*int fclose(stream) - close a stream
*
*Purpose:
* Flushes and closes a stream and frees any buffer associated
* with that stream, unless it was set with setbuf.
*
*Entry:
* FILE *stream - stream to close
*
*Exit:
* returns 0 if OK, EOF if fails (can't _flush, not a FILE, not open, etc.)
* closes the file -- affecting FILE structure
*
*Exceptions:
*
*******************************************************************************/
#ifdef MTHREAD /* multi-thread; define both fclose and _fclose_lk */
int _CRTAPI1 fclose (
FILE *stream
)
{
int result = EOF;
#ifdef MTHREAD
int index;
#endif
assert(stream != NULL);
/* If stream is a string, simply clear flag and return EOF */
if (stream->_flag & _IOSTRG)
stream->_flag = 0; /* IS THIS REALLY NEEDED ??? */
/* Stream is a real file. */
else {
#ifdef MTHREAD
index = _iob_index(stream);
#endif
_lock_str(index);
result = _fclose_lk(stream);
_unlock_str(index);
}
return(result);
}
/***
*int _fclose_lk() - close a stream (lock already held)
*
*Purpose:
* Core fclose() routine; assumes caller has stream lock held.
*
* [See fclose() above for more information.]
*
*Entry:
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
int _CRTAPI1 _fclose_lk (
FILE *str
)
{
REG1 FILE *stream;
REG2 int result = EOF;
#ifdef _CRUISER_
int tmp;
char tmpname[L_tmpnam];
char *ptmp;
#endif /* _CRUISER_ */
/* Init near stream pointer */
stream = str;
#else /* non multi-thread; just define fclose() */
int _CRTAPI1 fclose (
FILE *str
)
{
REG1 FILE *stream;
REG2 int result = EOF;
#ifdef _CRUISER_
int tmp;
char tmpname[L_tmpnam];
char *ptmp;
#endif /* _CRUISER_ */
/* Init near stream pointer */
stream = str;
if (stream->_flag & _IOSTRG) {
stream->_flag = 0;
return(EOF);
}
#endif
assert(str != NULL);
if (inuse(stream)) {
/* Stream is in use:
(1) flush stream
(2) free the buffer
(3) close the file
(4) delete the file if temporary
*/
#ifdef _POSIX_
result = _flush(stream);
#else /* ndef _POSIX_ */
result = _flush(stream);
#ifdef _CRUISER_
tmp = _tmpnum(stream);
#endif /* _CRUISER_ */
#endif /* _POSIX_ */
_freebuf(stream);
#ifdef _POSIX_
if (close(fileno(stream)) <0)
#else
if (_close(_fileno(stream)) < 0)
#endif
result = EOF;
#ifdef _CRUISER_
else if ( tmp ) {
/* File is temporary; build pathname and delete file */
strcpy( tmpname, _P_tmpdir );
ptmp = tmpname + sizeof(_P_tmpdir);
if (*(ptmp-2) != '\\')
strcat(tmpname,"\\");
else
ptmp--;
_itoa (tmp, ptmp, 10);
if ( _unlink( tmpname ) )
result = EOF ;
}
#else /* ndef _CRUISER_ */
else if ( stream->_tmpfname != NULL ) {
/*
* temporary file (i.e., one created by tmpfile()
* call). delete, if necessary (don't have to on
* Windows NT because it was done by the system when
* the handle was closed). also, free up the heap
* block holding the pathname.
*/
#ifdef _POSIX_
if ( unlink(stream->_tmpfname) )
result = EOF;
#endif
free(stream->_tmpfname);
}
#endif /* _CRUISER_ */
}
stream->_flag = 0;
return(result);
}
|