Alt+Ctrl+C

This commit is contained in:
2026-04-17 18:09:30 +08:00
parent 42b5925222
commit cb2406cbed
7 changed files with 310 additions and 7 deletions

View File

@@ -32,6 +32,7 @@ static int ush_cmd_help(void) {
ush_writeln(" kill <pid> [signal]"); ush_writeln(" kill <pid> [signal]");
ush_writeln(" jobs [-a] / ps [-a] [-u] / top [--once] [-n loops] [-d ticks]"); ush_writeln(" jobs [-a] / ps [-a] [-u] / top [--once] [-n loops] [-d ticks]");
ush_writeln(" sleep <ticks>"); ush_writeln(" sleep <ticks>");
ush_writeln(" spin (busy loop test for Alt+Ctrl+C)");
ush_writeln(" yield"); ush_writeln(" yield");
ush_writeln(" shutdown / restart"); ush_writeln(" shutdown / restart");
ush_writeln(" exit [code]"); ush_writeln(" exit [code]");

View File

@@ -0,0 +1,16 @@
#include <cleonos_syscall.h>
int cleonos_app_main(void) {
static const char banner[] =
"spin: busy loop started (test Alt+Ctrl+C force stop)\n";
volatile u64 noise = 0xC1E0C1E0ULL;
(void)cleonos_sys_tty_write(banner, (u64)(sizeof(banner) - 1U));
for (;;) {
noise ^= (noise << 7);
noise ^= (noise >> 9);
noise ^= 0x9E3779B97F4A7C15ULL;
noise += 0xA5A5A5A5A5A5A5A5ULL;
}
}

View File

@@ -9,11 +9,23 @@ clks_exec_call_on_stack_x86_64:
mov r11, rsp mov r11, rsp
mov rsp, rsi mov rsp, rsi
and rsp, -16 and rsp, -16
sub rsp, 8 sub rsp, 56
mov [rsp], r11 mov [rsp], r11
mov [rsp + 8], rbx
mov [rsp + 16], rbp
mov [rsp + 24], r12
mov [rsp + 32], r13
mov [rsp + 40], r14
mov [rsp + 48], r15
call rdi call rdi
mov rbx, [rsp + 8]
mov rbp, [rsp + 16]
mov r12, [rsp + 24]
mov r13, [rsp + 32]
mov r14, [rsp + 40]
mov r15, [rsp + 48]
mov rsp, [rsp] mov rsp, [rsp]
ret ret
@@ -22,6 +34,12 @@ clks_exec_call_on_stack_x86_64:
clks_exec_abort_to_caller_x86_64: clks_exec_abort_to_caller_x86_64:
mov rax, rsi mov rax, rsi
mov rsp, rdi mov rsp, rdi
mov rbx, [rsp + 8]
mov rbp, [rsp + 16]
mov r12, [rsp + 24]
mov r13, [rsp + 32]
mov r14, [rsp + 40]
mov r15, [rsp + 48]
mov rsp, [rsp] mov rsp, [rsp]
ret ret

View File

@@ -54,6 +54,8 @@ u64 clks_exec_proc_count(void);
clks_bool clks_exec_proc_pid_at(u64 index, u64 *out_pid); clks_bool clks_exec_proc_pid_at(u64 index, u64 *out_pid);
clks_bool clks_exec_proc_snapshot(u64 pid, struct clks_exec_proc_snapshot *out_snapshot); clks_bool clks_exec_proc_snapshot(u64 pid, struct clks_exec_proc_snapshot *out_snapshot);
u64 clks_exec_proc_kill(u64 pid, u64 signal); u64 clks_exec_proc_kill(u64 pid, u64 signal);
u64 clks_exec_force_stop_tty_running_process(u32 tty_index, u64 *out_pid);
clks_bool clks_exec_try_unwind_signaled_process(u64 interrupted_rip, u64 *io_rip, u64 *io_rdi, u64 *io_rsi);
clks_bool clks_exec_handle_exception(u64 vector, clks_bool clks_exec_handle_exception(u64 vector,
u64 error_code, u64 error_code,
u64 rip, u64 rip,

View File

@@ -23,6 +23,8 @@ typedef u64 (*clks_exec_entry_fn)(void);
#define CLKS_EXEC_ITEM_MAX 128U #define CLKS_EXEC_ITEM_MAX 128U
#define CLKS_EXEC_STATUS_SIGNAL_FLAG (1ULL << 63) #define CLKS_EXEC_STATUS_SIGNAL_FLAG (1ULL << 63)
#define CLKS_EXEC_DEFAULT_KILL_SIGNAL CLKS_EXEC_SIGNAL_TERM #define CLKS_EXEC_DEFAULT_KILL_SIGNAL CLKS_EXEC_SIGNAL_TERM
#define CLKS_EXEC_KERNEL_ADDR_BASE 0xFFFF800000000000ULL
#define CLKS_EXEC_UNWIND_CTX_BYTES 56ULL
enum clks_exec_proc_state { enum clks_exec_proc_state {
CLKS_EXEC_PROC_UNUSED = 0, CLKS_EXEC_PROC_UNUSED = 0,
@@ -72,8 +74,11 @@ static u64 clks_exec_next_pid = 1ULL;
static u64 clks_exec_pid_stack[CLKS_EXEC_MAX_DEPTH]; static u64 clks_exec_pid_stack[CLKS_EXEC_MAX_DEPTH];
static clks_bool clks_exec_exit_requested_stack[CLKS_EXEC_MAX_DEPTH]; static clks_bool clks_exec_exit_requested_stack[CLKS_EXEC_MAX_DEPTH];
static u64 clks_exec_exit_status_stack[CLKS_EXEC_MAX_DEPTH]; static u64 clks_exec_exit_status_stack[CLKS_EXEC_MAX_DEPTH];
static clks_bool clks_exec_stop_requested_stack[CLKS_EXEC_MAX_DEPTH];
static u64 clks_exec_unwind_slot_stack[CLKS_EXEC_MAX_DEPTH]; static u64 clks_exec_unwind_slot_stack[CLKS_EXEC_MAX_DEPTH];
static clks_bool clks_exec_unwind_slot_valid_stack[CLKS_EXEC_MAX_DEPTH]; static clks_bool clks_exec_unwind_slot_valid_stack[CLKS_EXEC_MAX_DEPTH];
static u64 clks_exec_image_begin_stack[CLKS_EXEC_MAX_DEPTH];
static u64 clks_exec_image_end_stack[CLKS_EXEC_MAX_DEPTH];
static u32 clks_exec_pid_stack_depth = 0U; static u32 clks_exec_pid_stack_depth = 0U;
static void clks_exec_serial_write_hex64(u64 value) { static void clks_exec_serial_write_hex64(u64 value) {
@@ -172,6 +177,30 @@ static clks_bool clks_exec_path_is_user_program(const char *path) {
return clks_exec_has_suffix(path, ".elf"); return clks_exec_has_suffix(path, ".elf");
} }
static clks_bool clks_exec_rip_is_current_user_context(u64 rip) {
i32 depth_index;
u64 image_begin;
u64 image_end;
if (rip < CLKS_EXEC_KERNEL_ADDR_BASE) {
return CLKS_TRUE;
}
if (clks_exec_pid_stack_depth == 0U) {
return CLKS_FALSE;
}
depth_index = (i32)(clks_exec_pid_stack_depth - 1U);
image_begin = clks_exec_image_begin_stack[(u32)depth_index];
image_end = clks_exec_image_end_stack[(u32)depth_index];
if (image_begin == 0ULL || image_end <= image_begin) {
return CLKS_FALSE;
}
return (rip >= image_begin && rip < image_end) ? CLKS_TRUE : CLKS_FALSE;
}
static void clks_exec_copy_path(char *dst, usize dst_size, const char *src) { static void clks_exec_copy_path(char *dst, usize dst_size, const char *src) {
usize i = 0U; usize i = 0U;
@@ -487,6 +516,29 @@ static void clks_exec_proc_mark_exited(struct clks_exec_proc_record *proc, u64 n
proc->exited_tick = now_tick; proc->exited_tick = now_tick;
} }
#if defined(CLKS_ARCH_X86_64)
static u64 clks_exec_read_rflags(void) {
u64 flags = 0ULL;
__asm__ volatile("pushfq; popq %0" : "=r"(flags) : : "memory");
return flags;
}
static clks_bool clks_exec_enable_interrupt_window(void) {
if ((clks_exec_read_rflags() & (1ULL << 9)) != 0ULL) {
return CLKS_FALSE;
}
__asm__ volatile("sti" : : : "memory");
return CLKS_TRUE;
}
static void clks_exec_restore_interrupt_window(clks_bool need_disable) {
if (need_disable == CLKS_TRUE) {
__asm__ volatile("cli" : : : "memory");
}
}
#endif
static clks_bool clks_exec_invoke_entry(void *entry_ptr, u32 depth_index, u64 *out_ret) { static clks_bool clks_exec_invoke_entry(void *entry_ptr, u32 depth_index, u64 *out_ret) {
if (entry_ptr == CLKS_NULL || out_ret == CLKS_NULL) { if (entry_ptr == CLKS_NULL || out_ret == CLKS_NULL) {
return CLKS_FALSE; return CLKS_FALSE;
@@ -497,6 +549,8 @@ static clks_bool clks_exec_invoke_entry(void *entry_ptr, u32 depth_index, u64 *o
void *stack_base = clks_kmalloc((usize)CLKS_EXEC_RUN_STACK_BYTES); void *stack_base = clks_kmalloc((usize)CLKS_EXEC_RUN_STACK_BYTES);
void *stack_top; void *stack_top;
u64 unwind_slot; u64 unwind_slot;
u64 call_ret = (u64)-1;
clks_bool restore_irq_disable = CLKS_FALSE;
if (stack_base == CLKS_NULL) { if (stack_base == CLKS_NULL) {
clks_log(CLKS_LOG_WARN, "EXEC", "RUN STACK ALLOC FAILED"); clks_log(CLKS_LOG_WARN, "EXEC", "RUN STACK ALLOC FAILED");
@@ -504,12 +558,22 @@ static clks_bool clks_exec_invoke_entry(void *entry_ptr, u32 depth_index, u64 *o
} }
stack_top = (void *)((u8 *)stack_base + (usize)CLKS_EXEC_RUN_STACK_BYTES); stack_top = (void *)((u8 *)stack_base + (usize)CLKS_EXEC_RUN_STACK_BYTES);
unwind_slot = (((u64)stack_top) & ~0xFULL) - 8ULL; unwind_slot = (((u64)stack_top) & ~0xFULL) - CLKS_EXEC_UNWIND_CTX_BYTES;
clks_exec_unwind_slot_stack[depth_index] = unwind_slot; clks_exec_unwind_slot_stack[depth_index] = unwind_slot;
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_TRUE; clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_TRUE;
*out_ret = clks_exec_call_on_stack_x86_64(entry_ptr, stack_top);
if (clks_exec_pending_dispatch_active == CLKS_FALSE) {
restore_irq_disable = clks_exec_enable_interrupt_window();
}
call_ret = clks_exec_call_on_stack_x86_64(entry_ptr, stack_top);
/* Close unwind window immediately after call returns to avoid IRQ race. */
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_FALSE; clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_FALSE;
clks_exec_unwind_slot_stack[depth_index] = 0ULL; clks_exec_unwind_slot_stack[depth_index] = 0ULL;
clks_exec_restore_interrupt_window(restore_irq_disable);
*out_ret = call_ret;
clks_kfree(stack_base); clks_kfree(stack_base);
return CLKS_TRUE; return CLKS_TRUE;
} }
@@ -566,6 +630,9 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
clks_exec_pid_stack[(u32)depth_index] = proc->pid; clks_exec_pid_stack[(u32)depth_index] = proc->pid;
clks_exec_exit_requested_stack[(u32)depth_index] = CLKS_FALSE; clks_exec_exit_requested_stack[(u32)depth_index] = CLKS_FALSE;
clks_exec_exit_status_stack[(u32)depth_index] = 0ULL; clks_exec_exit_status_stack[(u32)depth_index] = 0ULL;
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
clks_exec_pid_stack_depth++; clks_exec_pid_stack_depth++;
depth_pushed = CLKS_TRUE; depth_pushed = CLKS_TRUE;
@@ -600,6 +667,20 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
goto fail; goto fail;
} }
{
u64 image_begin = (u64)loaded.image_base;
u64 image_end = image_begin + loaded.image_size;
if (loaded.image_base == CLKS_NULL || loaded.image_size == 0ULL || image_end <= image_begin) {
clks_log(CLKS_LOG_WARN, "EXEC", "EXEC IMAGE WINDOW INVALID");
clks_log(CLKS_LOG_WARN, "EXEC", proc->path);
goto fail;
}
clks_exec_image_begin_stack[(u32)depth_index] = image_begin;
clks_exec_image_end_stack[(u32)depth_index] = image_end;
}
clks_exec_log_info_serial("EXEC RUN START"); clks_exec_log_info_serial("EXEC RUN START");
clks_exec_log_info_serial(proc->path); clks_exec_log_info_serial(proc->path);
clks_exec_log_hex_serial("ENTRY", info.entry); clks_exec_log_hex_serial("ENTRY", info.entry);
@@ -628,10 +709,22 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
clks_exec_log_hex_serial("RET", run_ret); clks_exec_log_hex_serial("RET", run_ret);
clks_exec_success++; clks_exec_success++;
if (clks_exec_stop_requested_stack[(u32)depth_index] == CLKS_TRUE) {
clks_exec_proc_mark_exited(proc, clks_interrupts_timer_ticks(), run_ret); u64 now_tick = clks_interrupts_timer_ticks();
clks_exec_proc_pause_runtime(proc, now_tick);
proc->state = CLKS_EXEC_PROC_STOPPED;
proc->exit_status = run_ret;
proc->exited_tick = 0ULL;
clks_exec_log_info_serial("RUN STOPPED");
clks_exec_log_info_serial(proc->path);
} else {
clks_exec_proc_mark_exited(proc, clks_interrupts_timer_ticks(), run_ret);
}
if (depth_pushed == CLKS_TRUE && clks_exec_pid_stack_depth > 0U) { if (depth_pushed == CLKS_TRUE && clks_exec_pid_stack_depth > 0U) {
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
clks_exec_pid_stack_depth--; clks_exec_pid_stack_depth--;
depth_pushed = CLKS_FALSE; depth_pushed = CLKS_FALSE;
} }
@@ -654,6 +747,9 @@ fail:
clks_exec_proc_mark_exited(proc, clks_interrupts_timer_ticks(), (u64)-1); clks_exec_proc_mark_exited(proc, clks_interrupts_timer_ticks(), (u64)-1);
if (depth_pushed == CLKS_TRUE && clks_exec_pid_stack_depth > 0U) { if (depth_pushed == CLKS_TRUE && clks_exec_pid_stack_depth > 0U) {
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
clks_exec_image_end_stack[(u32)depth_index] = 0ULL;
clks_exec_pid_stack_depth--; clks_exec_pid_stack_depth--;
} }
@@ -754,8 +850,11 @@ void clks_exec_init(void) {
clks_memset(clks_exec_pid_stack, 0, sizeof(clks_exec_pid_stack)); clks_memset(clks_exec_pid_stack, 0, sizeof(clks_exec_pid_stack));
clks_memset(clks_exec_exit_requested_stack, 0, sizeof(clks_exec_exit_requested_stack)); clks_memset(clks_exec_exit_requested_stack, 0, sizeof(clks_exec_exit_requested_stack));
clks_memset(clks_exec_exit_status_stack, 0, sizeof(clks_exec_exit_status_stack)); clks_memset(clks_exec_exit_status_stack, 0, sizeof(clks_exec_exit_status_stack));
clks_memset(clks_exec_stop_requested_stack, 0, sizeof(clks_exec_stop_requested_stack));
clks_memset(clks_exec_unwind_slot_stack, 0, sizeof(clks_exec_unwind_slot_stack)); clks_memset(clks_exec_unwind_slot_stack, 0, sizeof(clks_exec_unwind_slot_stack));
clks_memset(clks_exec_unwind_slot_valid_stack, 0, sizeof(clks_exec_unwind_slot_valid_stack)); clks_memset(clks_exec_unwind_slot_valid_stack, 0, sizeof(clks_exec_unwind_slot_valid_stack));
clks_memset(clks_exec_image_begin_stack, 0, sizeof(clks_exec_image_begin_stack));
clks_memset(clks_exec_image_end_stack, 0, sizeof(clks_exec_image_end_stack));
clks_memset(clks_exec_proc_table, 0, sizeof(clks_exec_proc_table)); clks_memset(clks_exec_proc_table, 0, sizeof(clks_exec_proc_table));
clks_exec_log_info_serial("PATH EXEC FRAMEWORK ONLINE"); clks_exec_log_info_serial("PATH EXEC FRAMEWORK ONLINE");
} }
@@ -1166,8 +1265,6 @@ u64 clks_exec_proc_kill(u64 pid, u64 signal) {
if (proc->state == CLKS_EXEC_PROC_STOPPED) { if (proc->state == CLKS_EXEC_PROC_STOPPED) {
return 1ULL; return 1ULL;
} }
return 0ULL;
} }
if (proc->state == CLKS_EXEC_PROC_PENDING || proc->state == CLKS_EXEC_PROC_STOPPED) { if (proc->state == CLKS_EXEC_PROC_PENDING || proc->state == CLKS_EXEC_PROC_STOPPED) {
@@ -1182,6 +1279,13 @@ u64 clks_exec_proc_kill(u64 pid, u64 signal) {
return 0ULL; return 0ULL;
} }
if (effective_signal == CLKS_EXEC_SIGNAL_STOP) {
clks_exec_exit_requested_stack[(u32)depth_index] = CLKS_TRUE;
clks_exec_exit_status_stack[(u32)depth_index] = status;
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_TRUE;
return 1ULL;
}
clks_exec_exit_requested_stack[(u32)depth_index] = CLKS_TRUE; clks_exec_exit_requested_stack[(u32)depth_index] = CLKS_TRUE;
clks_exec_exit_status_stack[(u32)depth_index] = status; clks_exec_exit_status_stack[(u32)depth_index] = status;
return 1ULL; return 1ULL;
@@ -1190,6 +1294,114 @@ u64 clks_exec_proc_kill(u64 pid, u64 signal) {
return 0ULL; return 0ULL;
} }
u64 clks_exec_force_stop_tty_running_process(u32 tty_index, u64 *out_pid) {
u32 tty_count = clks_tty_count();
u64 current_pid;
i32 slot;
u32 i;
if (out_pid != CLKS_NULL) {
*out_pid = 0ULL;
}
if (tty_count == 0U) {
tty_count = 1U;
}
if (tty_index >= tty_count) {
tty_index = 0U;
}
current_pid = clks_exec_current_pid();
if (current_pid != 0ULL) {
slot = clks_exec_proc_find_slot_by_pid(current_pid);
if (slot >= 0) {
const struct clks_exec_proc_record *proc = &clks_exec_proc_table[(u32)slot];
if (proc->used == CLKS_TRUE &&
proc->state == CLKS_EXEC_PROC_RUNNING &&
proc->tty_index == tty_index &&
clks_exec_path_is_user_program(proc->path) == CLKS_TRUE) {
u64 ret = clks_exec_proc_kill(current_pid, CLKS_EXEC_SIGNAL_STOP);
if (ret == 1ULL && out_pid != CLKS_NULL) {
*out_pid = current_pid;
}
return ret;
}
}
}
for (i = 0U; i < CLKS_EXEC_MAX_PROCS; i++) {
u64 ret;
if (clks_exec_proc_table[i].used != CLKS_TRUE ||
clks_exec_proc_table[i].state != CLKS_EXEC_PROC_RUNNING ||
clks_exec_proc_table[i].tty_index != tty_index ||
clks_exec_path_is_user_program(clks_exec_proc_table[i].path) == CLKS_FALSE) {
continue;
}
if (out_pid != CLKS_NULL) {
*out_pid = clks_exec_proc_table[i].pid;
}
ret = clks_exec_proc_kill(clks_exec_proc_table[i].pid, CLKS_EXEC_SIGNAL_STOP);
if (ret == 1ULL) {
return 1ULL;
}
}
return 0ULL;
}
clks_bool clks_exec_try_unwind_signaled_process(u64 interrupted_rip,
u64 *io_rip,
u64 *io_rdi,
u64 *io_rsi) {
i32 depth_index;
if (io_rip == CLKS_NULL || io_rdi == CLKS_NULL || io_rsi == CLKS_NULL) {
return CLKS_FALSE;
}
if (clks_exec_is_running() == CLKS_FALSE || clks_exec_current_path_is_user() == CLKS_FALSE) {
return CLKS_FALSE;
}
if (clks_exec_rip_is_current_user_context(interrupted_rip) == CLKS_FALSE) {
return CLKS_FALSE;
}
depth_index = clks_exec_current_depth_index();
if (depth_index < 0) {
return CLKS_FALSE;
}
if (clks_exec_stop_requested_stack[(u32)depth_index] == CLKS_FALSE) {
return CLKS_FALSE;
}
#if defined(CLKS_ARCH_X86_64)
if (clks_exec_unwind_slot_valid_stack[(u32)depth_index] == CLKS_FALSE) {
return CLKS_FALSE;
}
*io_rip = (u64)clks_exec_abort_to_caller_x86_64;
*io_rdi = clks_exec_unwind_slot_stack[(u32)depth_index];
*io_rsi = clks_exec_exit_status_stack[(u32)depth_index];
return CLKS_TRUE;
#else
(void)depth_index;
return CLKS_FALSE;
#endif
}
clks_bool clks_exec_handle_exception(u64 vector, clks_bool clks_exec_handle_exception(u64 vector,
u64 error_code, u64 error_code,
u64 rip, u64 rip,
@@ -1205,6 +1417,10 @@ clks_bool clks_exec_handle_exception(u64 vector,
return CLKS_FALSE; return CLKS_FALSE;
} }
if (clks_exec_rip_is_current_user_context(rip) == CLKS_FALSE) {
return CLKS_FALSE;
}
depth_index = clks_exec_current_depth_index(); depth_index = clks_exec_current_depth_index();
proc = clks_exec_current_proc(); proc = clks_exec_current_proc();

View File

@@ -279,6 +279,7 @@ void clks_interrupt_dispatch(struct clks_interrupt_frame *frame) {
} }
if (vector >= CLKS_IRQ_BASE && vector <= CLKS_IRQ_LAST) { if (vector >= CLKS_IRQ_BASE && vector <= CLKS_IRQ_LAST) {
(void)clks_exec_try_unwind_signaled_process(frame->rip, &frame->rip, &frame->rdi, &frame->rsi);
clks_pic_send_eoi(vector); clks_pic_send_eoi(vector);
} }
} }

View File

@@ -13,6 +13,7 @@
#define CLKS_SC_F2 0x3CU #define CLKS_SC_F2 0x3CU
#define CLKS_SC_F3 0x3DU #define CLKS_SC_F3 0x3DU
#define CLKS_SC_F4 0x3EU #define CLKS_SC_F4 0x3EU
#define CLKS_SC_C 0x2EU
#define CLKS_SC_EXT_PREFIX 0xE0U #define CLKS_SC_EXT_PREFIX 0xE0U
#define CLKS_SC_EXT_HOME 0x47U #define CLKS_SC_EXT_HOME 0x47U
@@ -62,6 +63,7 @@ static clks_bool clks_kbd_rshift_down = CLKS_FALSE;
static clks_bool clks_kbd_lctrl_down = CLKS_FALSE; static clks_bool clks_kbd_lctrl_down = CLKS_FALSE;
static clks_bool clks_kbd_rctrl_down = CLKS_FALSE; static clks_bool clks_kbd_rctrl_down = CLKS_FALSE;
static clks_bool clks_kbd_e0_prefix = CLKS_FALSE; static clks_bool clks_kbd_e0_prefix = CLKS_FALSE;
static clks_bool clks_kbd_force_stop_latch = CLKS_FALSE;
static u64 clks_kbd_hotkey_switches = 0ULL; static u64 clks_kbd_hotkey_switches = 0ULL;
static u64 clks_kbd_push_count = 0ULL; static u64 clks_kbd_push_count = 0ULL;
@@ -202,6 +204,35 @@ static clks_bool clks_keyboard_try_emit_ctrl_shortcut(u8 code, u32 tty_index) {
return CLKS_TRUE; return CLKS_TRUE;
} }
static clks_bool clks_keyboard_try_force_stop_hotkey(u8 code) {
u64 pid = 0ULL;
u64 stop_ret;
if (code != CLKS_SC_C) {
return CLKS_FALSE;
}
if (clks_kbd_alt_down != CLKS_TRUE || clks_keyboard_ctrl_active() == CLKS_FALSE) {
return CLKS_FALSE;
}
if (clks_kbd_force_stop_latch == CLKS_TRUE) {
return CLKS_TRUE;
}
clks_kbd_force_stop_latch = CLKS_TRUE;
stop_ret = clks_exec_force_stop_tty_running_process(clks_tty_active(), &pid);
if (stop_ret == 1ULL) {
clks_log(CLKS_LOG_WARN, "KBD", "HOTKEY CTRL+ALT+C FORCE STOP");
clks_log_hex(CLKS_LOG_WARN, "KBD", "PID", pid);
} else {
clks_log(CLKS_LOG_WARN, "KBD", "HOTKEY CTRL+ALT+C NO RUNNING USER PROC");
}
return CLKS_TRUE;
}
void clks_keyboard_init(void) { void clks_keyboard_init(void) {
u32 tty; u32 tty;
@@ -217,6 +248,7 @@ void clks_keyboard_init(void) {
clks_kbd_lctrl_down = CLKS_FALSE; clks_kbd_lctrl_down = CLKS_FALSE;
clks_kbd_rctrl_down = CLKS_FALSE; clks_kbd_rctrl_down = CLKS_FALSE;
clks_kbd_e0_prefix = CLKS_FALSE; clks_kbd_e0_prefix = CLKS_FALSE;
clks_kbd_force_stop_latch = CLKS_FALSE;
clks_kbd_hotkey_switches = 0ULL; clks_kbd_hotkey_switches = 0ULL;
clks_kbd_push_count = 0ULL; clks_kbd_push_count = 0ULL;
clks_kbd_pop_count = 0ULL; clks_kbd_pop_count = 0ULL;
@@ -242,16 +274,25 @@ void clks_keyboard_handle_scancode(u8 scancode) {
if (code == CLKS_SC_CTRL) { if (code == CLKS_SC_CTRL) {
if (clks_kbd_e0_prefix == CLKS_TRUE) { if (clks_kbd_e0_prefix == CLKS_TRUE) {
clks_kbd_rctrl_down = (released == CLKS_FALSE) ? CLKS_TRUE : CLKS_FALSE; clks_kbd_rctrl_down = (released == CLKS_FALSE) ? CLKS_TRUE : CLKS_FALSE;
if (released == CLKS_TRUE) {
clks_kbd_force_stop_latch = CLKS_FALSE;
}
clks_kbd_e0_prefix = CLKS_FALSE; clks_kbd_e0_prefix = CLKS_FALSE;
return; return;
} }
clks_kbd_lctrl_down = (released == CLKS_FALSE) ? CLKS_TRUE : CLKS_FALSE; clks_kbd_lctrl_down = (released == CLKS_FALSE) ? CLKS_TRUE : CLKS_FALSE;
if (released == CLKS_TRUE) {
clks_kbd_force_stop_latch = CLKS_FALSE;
}
return; return;
} }
if (code == CLKS_SC_ALT) { if (code == CLKS_SC_ALT) {
clks_kbd_alt_down = (released == CLKS_FALSE) ? CLKS_TRUE : CLKS_FALSE; clks_kbd_alt_down = (released == CLKS_FALSE) ? CLKS_TRUE : CLKS_FALSE;
if (released == CLKS_TRUE) {
clks_kbd_force_stop_latch = CLKS_FALSE;
}
if (clks_kbd_e0_prefix == CLKS_TRUE) { if (clks_kbd_e0_prefix == CLKS_TRUE) {
clks_kbd_e0_prefix = CLKS_FALSE; clks_kbd_e0_prefix = CLKS_FALSE;
@@ -271,6 +312,10 @@ void clks_keyboard_handle_scancode(u8 scancode) {
} }
if (released == CLKS_TRUE) { if (released == CLKS_TRUE) {
if (code == CLKS_SC_C) {
clks_kbd_force_stop_latch = CLKS_FALSE;
}
if (clks_kbd_e0_prefix == CLKS_TRUE) { if (clks_kbd_e0_prefix == CLKS_TRUE) {
clks_kbd_e0_prefix = CLKS_FALSE; clks_kbd_e0_prefix = CLKS_FALSE;
} }
@@ -327,6 +372,10 @@ void clks_keyboard_handle_scancode(u8 scancode) {
u32 active_tty = clks_tty_active(); u32 active_tty = clks_tty_active();
char translated; char translated;
if (clks_keyboard_try_force_stop_hotkey(code) == CLKS_TRUE) {
return;
}
if (clks_keyboard_try_emit_ctrl_shortcut(code, active_tty) == CLKS_TRUE) { if (clks_keyboard_try_emit_ctrl_shortcut(code, active_tty) == CLKS_TRUE) {
return; return;
} }