Reactos
at master 87 lines 2.3 kB view raw
1// 2// fclose.cpp 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// Defines fclose(), which closes a stdio stream. 7// 8#include <corecrt_internal_stdio.h> 9#include <corecrt_internal_ptd_propagation.h> 10 11 12 13// Closes a stdio stream after flushing the stream and freeing any buffer 14// associated with the stream (unless the buffer was set with setbuf). Returns 15// zero on success; EOF on failure (e.g., if the flush fails, or it is not a 16// valid file or the file is not open, etc.). 17static int __cdecl _fclose_nolock_internal(FILE* const public_stream, __crt_cached_ptd_host& ptd) 18{ 19 __crt_stdio_stream const stream(public_stream); 20 21 _UCRT_VALIDATE_RETURN(ptd, stream.valid(), EINVAL, EOF); 22 23 int result = EOF; 24 25 if (stream.is_in_use()) 26 { 27 result = __acrt_stdio_flush_nolock(stream.public_stream(), ptd); 28 __acrt_stdio_free_buffer_nolock(stream.public_stream()); 29 30 if (_close_internal(_fileno(stream.public_stream()), ptd) < 0) 31 { 32 result = EOF; 33 } 34 else if (stream->_tmpfname != nullptr) 35 { 36 _free_crt(stream->_tmpfname); 37 stream->_tmpfname = nullptr; 38 } 39 } 40 41 __acrt_stdio_free_stream(stream); 42 43 return result; 44} 45 46extern "C" int __cdecl _fclose_nolock(FILE* const public_stream) 47{ 48 __crt_cached_ptd_host ptd; 49 return _fclose_nolock_internal(public_stream, ptd); 50} 51 52static int __cdecl _fclose_internal(FILE* const public_stream, __crt_cached_ptd_host& ptd) 53{ 54 __crt_stdio_stream const stream(public_stream); 55 56 _UCRT_VALIDATE_RETURN(ptd, stream.valid(), EINVAL, EOF); 57 58 // If the stream is backed by a string, it requires no synchronization, 59 // flushing, etc., so we can simply free it, which resets all of its 60 // data to the defaults. 61 if (stream.is_string_backed()) 62 { 63 __acrt_stdio_free_stream(stream); 64 return EOF; 65 } 66 67 int return_value = 0; 68 69 _lock_file(stream.public_stream()); 70 __try 71 { 72 return_value = _fclose_nolock_internal(stream.public_stream(), ptd); 73 } 74 __finally 75 { 76 _unlock_file(stream.public_stream()); 77 } 78 __endtry 79 80 return return_value; 81} 82 83extern "C" int __cdecl fclose(FILE* const public_stream) 84{ 85 __crt_cached_ptd_host ptd; 86 return _fclose_internal(public_stream, ptd); 87}