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(