summaryrefslogtreecommitdiffstats
path: root/private/crt32/stdio/fclose.c
blob: f6d93fd383c7fedf7e0b8e7a7f84df2cf16ce2ae (plain) (blame)
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);
}