1 // 2 // setmode.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Defines _setmode(), which sets the translation mode for a file, and 7 // _set_fmode() and _get_fmode(), which control the global default translation 8 // mode. 9 // 10 #include <corecrt_internal_lowio.h> 11 #include <stdlib.h> 12 13 14 15 // Sets the file translation mode. This changes the file mode to text or binary, 16 // depending on the mode argument. This affects whether reads and writes on the 17 // file translate between CRLF and LF. Returns the old file translation mode on 18 // success, or -1 on failure. 19 extern "C" int __cdecl _setmode(int const fh, int const mode) 20 { 21 _VALIDATE_RETURN(mode == _O_TEXT || 22 mode == _O_BINARY || 23 mode == _O_WTEXT || 24 mode == _O_U8TEXT || 25 mode == _O_U16TEXT, 26 EINVAL, -1); 27 28 _CHECK_FH_RETURN(fh, EBADF, -1); 29 _VALIDATE_RETURN((fh >= 0 && (unsigned)fh < (unsigned)_nhandle), EBADF, -1); 30 _VALIDATE_RETURN((_osfile(fh) & FOPEN), EBADF, -1); 31 32 __acrt_lowio_lock_fh(fh); 33 int result = -1; 34 __try 35 { 36 if ((_osfile(fh) & FOPEN) == 0) 37 { 38 errno = EBADF; 39 _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0)); 40 __leave; 41 } 42 43 result = _setmode_nolock(fh, mode); 44 } 45 __finally 46 { 47 __acrt_lowio_unlock_fh(fh); 48 } 49 __endtry 50 return result; 51 } 52 53 54 55 extern "C" int __cdecl _setmode_nolock(int const fh, int const mode) 56 { 57 int const old_mode = _osfile(fh) & FTEXT; 58 __crt_lowio_text_mode const old_textmode = _textmode(fh); 59 60 switch (mode) 61 { 62 case _O_BINARY: 63 _osfile(fh) &= ~FTEXT; 64 break; 65 66 case _O_TEXT: 67 _osfile(fh) |= FTEXT; 68 _textmode(fh) = __crt_lowio_text_mode::ansi; 69 break; 70 71 case _O_U8TEXT: 72 _osfile(fh) |= FTEXT; 73 _textmode(fh) = __crt_lowio_text_mode::utf8; 74 break; 75 76 case _O_U16TEXT: 77 case _O_WTEXT: 78 _osfile(fh) |= FTEXT; 79 _textmode(fh) = __crt_lowio_text_mode::utf16le; 80 break; 81 } 82 83 if (old_mode == 0) 84 return _O_BINARY; 85 86 if (old_textmode == __crt_lowio_text_mode::ansi) 87 { 88 return _O_TEXT; 89 } 90 else if (old_textmode == __crt_lowio_text_mode::utf8) 91 { 92 return _O_U8TEXT; 93 } 94 95 return _O_WTEXT; 96 } 97 98 99 100 extern "C" errno_t __cdecl _set_fmode(int const mode) 101 { 102 _VALIDATE_RETURN_ERRCODE(mode == _O_TEXT || mode == _O_BINARY || mode == _O_WTEXT, EINVAL); 103 104 _BEGIN_SECURE_CRT_DEPRECATION_DISABLE 105 _InterlockedExchange(reinterpret_cast<long*>(&_fmode.value()), mode); 106 _END_SECURE_CRT_DEPRECATION_DISABLE 107 108 return 0; 109 } 110 111 112 113 extern "C" errno_t __cdecl _get_fmode(int* const pMode) 114 { 115 _VALIDATE_RETURN_ERRCODE(pMode != nullptr, EINVAL); 116 117 _BEGIN_SECURE_CRT_DEPRECATION_DISABLE 118 *pMode = __crt_interlocked_read(&_fmode.value()); 119 _END_SECURE_CRT_DEPRECATION_DISABLE 120 121 return 0; 122 } 123