This repository has been archived by the owner on Dec 8, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 206
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
aec5e2d
commit b84814e
Showing
11 changed files
with
285 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
#include <Windows.h> | ||
#include <corecrt_wstdio.h> | ||
#include <stdio.h> | ||
#include <corecrt_internal_stdio.h> | ||
|
||
extern "C" __declspec(dllimport) extern _iobuf _iob[_IOB_ENTRIES]; | ||
|
||
|
||
namespace VC_LTL_Thunks | ||
{ | ||
extern "C" __declspec(dllimport) wint_t __cdecl fputwc( | ||
_In_ wchar_t _Character, | ||
_Inout_ FILE* _Stream); | ||
|
||
extern "C" __declspec(dllimport) size_t __cdecl fwrite( | ||
_In_reads_bytes_(_ElementSize * _ElementCount) void const* _Buffer, | ||
_In_ size_t _ElementSize, | ||
_In_ size_t _ElementCount, | ||
_Inout_ FILE* _Stream | ||
); | ||
|
||
extern "C" __declspec(dllimport) int __cdecl fputc( | ||
_In_ int _Character, | ||
_Inout_ FILE* _Stream | ||
); | ||
} | ||
|
||
extern "C" wint_t __cdecl fputwc( | ||
wchar_t _Character, | ||
FILE* _Stream) | ||
{ | ||
if ((_Character & (~0x7F)) | ||
&&(_Stream == /*stdout*/&_iob[1] || _Stream == /*stderr*/&_iob[2])) | ||
{ | ||
_lock_file(_Stream); | ||
auto Success = __acrt_stdio_begin_temporary_buffering_nolock(_Stream); | ||
wint_t result = VC_LTL_Thunks::fputwc(_Character, _Stream); | ||
__acrt_stdio_end_temporary_buffering_nolock(Success, _Stream); | ||
_unlock_file(_Stream); | ||
|
||
return result; | ||
} | ||
|
||
return VC_LTL_Thunks::fputwc(_Character, _Stream); | ||
} | ||
|
||
extern "C" wint_t __cdecl putwc( | ||
wchar_t _Character, | ||
FILE* _Stream | ||
) | ||
{ | ||
return fputwc(_Character, _Stream); | ||
} | ||
|
||
extern "C" wint_t __cdecl _fputwchar( | ||
wchar_t _Character | ||
) | ||
{ | ||
return fputwc(_Character,/*stdout*/&_iob[1]); | ||
} | ||
|
||
extern "C" size_t __cdecl fwrite( | ||
void const* const buffer, | ||
size_t const size, | ||
size_t const count, | ||
FILE* const stream | ||
) | ||
{ | ||
if (stream == /*stdout*/&_iob[1] || stream == /*stderr*/&_iob[2]) | ||
{ | ||
_lock_file(stream); | ||
auto Success = __acrt_stdio_begin_temporary_buffering_nolock(stream); | ||
wint_t result = VC_LTL_Thunks::fwrite(buffer, size, count, stream); | ||
__acrt_stdio_end_temporary_buffering_nolock(Success, stream); | ||
_unlock_file(stream); | ||
|
||
return result; | ||
} | ||
else | ||
{ | ||
return VC_LTL_Thunks::fwrite(buffer, size, count, stream); | ||
} | ||
} | ||
|
||
extern "C" int __cdecl fputc(int const c, FILE* const stream) | ||
{ | ||
if ((c & 0x80) | ||
&&(stream == /*stdout*/&_iob[1] || stream == /*stderr*/&_iob[2])) | ||
{ | ||
_lock_file(stream); | ||
static bool stdout_buffer_used = false; | ||
static bool stderr_buffer_used = false; | ||
|
||
static char stdout_buffer[2]; | ||
|
||
static char stderr_buffer[2]; | ||
|
||
|
||
bool* buffer_used; | ||
char* buffer; | ||
if (stream == /*stdout*/&_iob[1]) | ||
{ | ||
buffer_used = &stdout_buffer_used; | ||
buffer = stdout_buffer; | ||
} | ||
else | ||
{ | ||
buffer_used = &stderr_buffer_used; | ||
buffer = stderr_buffer; | ||
} | ||
|
||
if (*buffer_used) | ||
{ | ||
buffer[1] = c; | ||
auto Success = __acrt_stdio_begin_temporary_buffering_nolock(stream); | ||
auto result = VC_LTL_Thunks::fwrite(buffer, 1, 2, stream); | ||
__acrt_stdio_end_temporary_buffering_nolock(Success, stream); | ||
_unlock_file(stream); | ||
|
||
*buffer_used = false; | ||
|
||
|
||
return result ? c : EOF; | ||
} | ||
else if (isleadbyte(c)) | ||
{ | ||
*buffer_used = true; | ||
buffer[0] = c; | ||
return c; | ||
} | ||
} | ||
|
||
return VC_LTL_Thunks::fputc(c, stream); | ||
} | ||
|
||
|
||
|
||
extern "C" int __cdecl putc( | ||
int _Character, | ||
FILE* _Stream | ||
) | ||
{ | ||
return fputc(_Character, _Stream); | ||
} | ||
|
||
extern "C" int __cdecl _fputchar( | ||
int _Character | ||
) | ||
{ | ||
return fputc(_Character, /*stdout*/&_iob[1]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#include <corecrt_internal_stdio.h> | ||
|
||
// Buffer pointers for stdout and stderr | ||
extern "C" void* __acrt_stdout_buffer = nullptr; | ||
extern "C" void* __acrt_stderr_buffer = nullptr; | ||
|
||
extern "C" __declspec(dllimport) extern _iobuf _iob[_IOB_ENTRIES]; | ||
|
||
extern "C" bool __cdecl __acrt_stdio_begin_temporary_buffering_nolock( | ||
FILE* const public_stream | ||
) | ||
{ | ||
// Do nothing if the stream is not backed by a TTY device | ||
if (!_isatty(_fileno(public_stream))) | ||
return false; | ||
|
||
|
||
void** buffer; | ||
if (public_stream == /*stdout*/&_iob[1]) | ||
buffer = &__acrt_stdout_buffer; | ||
else if (public_stream == /*stderr*/&_iob[2]) | ||
buffer = &__acrt_stderr_buffer; | ||
else | ||
return false; | ||
|
||
//_IOBUFFER_SETVBUF | | ||
if (public_stream->_flags & 0x10C) | ||
return false; | ||
|
||
public_stream->_flags |= 0x1102u; | ||
|
||
if (*buffer == nullptr) | ||
{ | ||
auto tmp = malloc(_INTERNAL_BUFSIZ); | ||
|
||
if (tmp == nullptr) | ||
{ | ||
// If we failed to allocate a buffer, use the small character buffer: | ||
public_stream->_base = reinterpret_cast<char*>(&public_stream->_charbuf); | ||
public_stream->_ptr = reinterpret_cast<char*>(&public_stream->_charbuf); | ||
public_stream->_cnt = 2; | ||
public_stream->_bufsiz = 2; | ||
return true; | ||
} | ||
|
||
*buffer = tmp; | ||
} | ||
|
||
// Otherwise, we have a new buffer, so set it up for use: | ||
public_stream->_base = reinterpret_cast<char*>(*buffer); | ||
public_stream->_ptr = reinterpret_cast<char*>(*buffer); | ||
public_stream->_cnt = _INTERNAL_BUFSIZ; | ||
public_stream->_bufsiz = _INTERNAL_BUFSIZ; | ||
return true; | ||
} | ||
|
||
|
||
// If the stream currently has a temporary buffer that was set via a call to | ||
// __acrt_stdio_begin_temporary_buffering_nolock(), and if the flag value is | ||
// 1, this function flushes the stream and disables buffering of the stream. | ||
extern "C" void __cdecl __acrt_stdio_end_temporary_buffering_nolock( | ||
bool const flag, | ||
FILE* const public_stream | ||
) | ||
{ | ||
if (!flag) | ||
return; | ||
|
||
if (public_stream->_flags & 0x1000) | ||
{ | ||
//_flush(public_stream);,凑合用 fflush 吧,虽然会多进一次临界区但是影响不大。 | ||
fflush(public_stream); | ||
|
||
public_stream->_flags &= 0xFFFFEEFF; | ||
public_stream->_bufsiz = 0; | ||
public_stream->_ptr = 0; | ||
public_stream->_base = 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.