Skip to content

Commit b772569

Browse files
committed
Ignore CTRL-C in alias after CreateProcess (#140)
If CTRL-C terminates the alias but the child ignores CTRL-C, the parent of the alias (shell, make, etc.) will be led to beleive the real command terminated despite continuing to run. Because a null CTRL-C handler is inherited, the alias sets a real handler that ignores all CTRL events, relying on the child to make a decision. To minimize the window between starting to ignore CTRL-C and spawning the child, SetConsoleCtrlHandler is called as late as possible.
1 parent 7d6330a commit b772569

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

src/alias.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ typedef char16_t c16;
3838

3939
typedef struct {} *handle;
4040

41+
typedef b32 __stdcall handler(i32);
42+
4143
typedef struct {
4244
u32 cb;
4345
uptr a, b, c;
@@ -61,6 +63,7 @@ W32 i32 GetExitCodeProcess(handle, u32 *);
6163
W32 u32 GetFullPathNameW(c16 *, u32, c16 *, c16 *);
6264
W32 u32 GetModuleFileNameW(handle, c16 *, u32);
6365
W32 handle GetStdHandle(u32);
66+
W32 b32 SetConsoleCtrlHandler(handler, b32);
6467
W32 byte *VirtualAlloc(byte *, usize, u32, u32);
6568
W32 b32 VirtualFree(byte *, usize, u32);
6669
W32 u32 WaitForSingleObject(handle, u32);
@@ -156,6 +159,11 @@ static si *newstartupinfo(byte **heap)
156159
return s;
157160
}
158161

162+
static b32 __stdcall ignorectrlc(i32)
163+
{
164+
return 1;
165+
}
166+
159167
static i32 aliasmain(void)
160168
{
161169
byte *heap_start = VirtualAlloc(0, 1<<18, 0x3000, 4);
@@ -204,6 +212,7 @@ static i32 aliasmain(void)
204212

205213
si *si = newstartupinfo(&heap);
206214
pi pi;
215+
SetConsoleCtrlHandler(ignorectrlc, 1); // NOTE: set as late a possible
207216
if (!CreateProcessW(exe->buf, cmd->buf, 0, 0, 1, 0, 0, 0, si, &pi)) {
208217
static const u8 msg[] = ERR("could not start process\n");
209218
return fatal((u8 *)msg, lengthof(msg));

src/busybox-alias.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ typedef char16_t c16;
1919

2020
typedef struct {} *handle;
2121

22+
typedef b32 __stdcall handler(i32);
23+
2224
typedef struct {
2325
u32 cb;
2426
void *a, *b, *c;
@@ -41,6 +43,7 @@ W32 c16 *GetCommandLineW(void);
4143
W32 i32 GetExitCodeProcess(handle, u32 *);
4244
W32 u32 GetModuleFileNameW(handle, c16 *, u32);
4345
W32 handle GetStdHandle(u32);
46+
W32 b32 SetConsoleCtrlHandler(handler, b32);
4447
W32 u32 WaitForSingleObject(handle, u32);
4548
W32 b32 WriteFile(handle, u8 *, u32, u32 *, void *);
4649

@@ -84,6 +87,11 @@ static u32 fatal(u8 *msg, i32 len)
8487
return 0x17e;
8588
}
8689

90+
static b32 __stdcall ignorectrlc(i32)
91+
{
92+
return 1;
93+
}
94+
8795
static u32 run(void)
8896
{
8997
c16 buf[MAX_PATH];
@@ -103,6 +111,7 @@ static u32 run(void)
103111
si.cb = sizeof(si);
104112
pi pi;
105113
c16 *cmdline = GetCommandLineW();
114+
SetConsoleCtrlHandler(ignorectrlc, 1); // NOTE: set as late a possible
106115
if (!CreateProcessW(exe.buf, cmdline, 0, 0, 1, 0, 0, 0, &si, &pi)) {
107116
static u8 msg[] = "w64devkit: could not start busybox.exe\n";
108117
return fatal(msg, lengthof(msg));

0 commit comments

Comments
 (0)