Restore Windows command prompt mode on exit

Fixes #60
This commit is contained in:
Justine Tunney 2021-02-27 12:53:51 -08:00
parent 218ef49147
commit 35c7edac49
3 changed files with 33 additions and 34 deletions

View file

@ -16,13 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/bits/pushpop.h"
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/dce.h"
#include "libc/nt/console.h"
#include "libc/nt/enum/consolemodeflags.h"
#include "libc/nt/pedef.internal.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/internal.h" #include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
extern const uintptr_t __fini_array_start[] __attribute__((__weak__));
extern const uintptr_t __fini_array_end[] __attribute__((__weak__));
/** /**
* Exits process with grace. * Exits process with grace.
* *
@ -42,5 +45,11 @@ wontreturn void exit(int exitcode) {
for (p = __fini_array_end; p > __fini_array_start;) { for (p = __fini_array_end; p > __fini_array_start;) {
((void (*)(void))(*--p))(); ((void (*)(void))(*--p))();
} }
if (SupportsWindows() && __ntconsolemode) {
SetConsoleMode(GetStdHandle(pushpop(kNtStdInputHandle)), __ntconsolemode);
SetConsoleMode(GetStdHandle(pushpop(kNtStdOutputHandle)),
kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput |
kNtEnableVirtualTerminalProcessing);
}
_Exit(exitcode); _Exit(exitcode);
} }

View file

@ -12,9 +12,10 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
extern hidden bool _mmap_asan_mode; extern uint32_t __ntconsolemode;
extern hidden char **g_freebsdhint; extern const char v_ntsubsystem[] __attribute__((__weak__));
extern hidden void *g_stacktop; extern const uintptr_t __fini_array_end[] __attribute__((__weak__));
extern const uintptr_t __fini_array_start[] __attribute__((__weak__));
void _init(void) hidden; void _init(void) hidden;
void *__cxa_finalize(void *) hidden; void *__cxa_finalize(void *) hidden;

View file

@ -61,6 +61,8 @@ struct WinArgs {
char envblock[ARG_MAX]; char envblock[ARG_MAX];
}; };
uint32_t __ntconsolemode;
static noasan textwindows void MakeLongDoubleLongAgain(void) { static noasan textwindows void MakeLongDoubleLongAgain(void) {
/* 8087 FPU Control Word /* 8087 FPU Control Word
IM: Invalid Operation IM: Invalid Operation
@ -79,45 +81,32 @@ static noasan textwindows void MakeLongDoubleLongAgain(void) {
asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw)); asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw));
} }
static noasan textwindows void NormalizeCmdExe(int version) {
uint32_t mode;
int64_t handle, hstdin, hstdout, hstderr;
if ((int)weakaddr("v_ntsubsystem") == kNtImageSubsystemWindowsCui &&
version >= 10) {
hstdin = GetStdHandle(pushpop(kNtStdInputHandle));
hstdout = GetStdHandle(pushpop(kNtStdOutputHandle));
hstderr = GetStdHandle(pushpop(kNtStdErrorHandle));
if (GetFileType((handle = hstdin)) == kNtFileTypeChar) {
SetConsoleCP(kNtCpUtf8);
GetConsoleMode(handle, &mode);
SetConsoleMode(handle, mode | kNtEnableProcessedInput |
kNtEnableEchoInput | kNtEnableLineInput |
kNtEnableWindowInput |
kNtEnableVirtualTerminalInput);
}
if (GetFileType((handle = hstdout)) == kNtFileTypeChar ||
GetFileType((handle = hstderr)) == kNtFileTypeChar) {
SetConsoleOutputCP(kNtCpUtf8);
GetConsoleMode(handle, &mode);
SetConsoleMode(
handle, mode | kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput |
(version >= 10 ? kNtEnableVirtualTerminalProcessing : 0));
}
}
}
static noasan textwindows wontreturn void WinMainNew(void) { static noasan textwindows wontreturn void WinMainNew(void) {
int64_t h; int64_t h;
int version; int version;
size_t size; size_t size;
int i, count; int i, count;
uint64_t addr; uint64_t addr;
int64_t inhand;
struct WinArgs *wa; struct WinArgs *wa;
const char16_t *env16; const char16_t *env16;
extern char os asm("__hostos"); extern char os asm("__hostos");
os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */ os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */
version = NtGetPeb()->OSMajorVersion; version = NtGetPeb()->OSMajorVersion;
NormalizeCmdExe(version); if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
SetConsoleCP(kNtCpUtf8);
SetConsoleOutputCP(kNtCpUtf8);
inhand = GetStdHandle(pushpop(kNtStdInputHandle));
GetConsoleMode(inhand, &__ntconsolemode);
SetConsoleMode(inhand, kNtEnableProcessedInput | kNtEnableLineInput |
kNtEnableEchoInput | kNtEnableMouseInput |
kNtEnableQuickEditMode | kNtEnableExtendedFlags |
kNtEnableAutoPosition |
kNtEnableVirtualTerminalInput);
SetConsoleMode(GetStdHandle(pushpop(kNtStdOutputHandle)),
kNtEnableProcessedOutput | kNtEnableWrapAtEolOutput |
kNtEnableVirtualTerminalProcessing);
}
addr = version < 10 ? 0xff00000 : 0x777000000000; addr = version < 10 ? 0xff00000 : 0x777000000000;
size = ROUNDUP(STACKSIZE + sizeof(struct WinArgs), FRAMESIZE); size = ROUNDUP(STACKSIZE + sizeof(struct WinArgs), FRAMESIZE);
MapViewOfFileExNuma((_mmi.p[0].h = CreateFileMappingNuma( MapViewOfFileExNuma((_mmi.p[0].h = CreateFileMappingNuma(