feat: add spawn_shell dispatch to keybind

This commit is contained in:
DreamMaoMao 2025-08-31 09:26:58 +08:00
parent 795a2ec9fb
commit 33d6de6bcf
3 changed files with 31 additions and 1 deletions

View file

@ -759,6 +759,9 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
} else if (strcmp(func_name, "spawn") == 0) {
func = spawn;
(*arg).v = strdup(arg_value);
} else if (strcmp(func_name, "spawn_shell") == 0) {
func = spawn_shell;
(*arg).v = strdup(arg_value);
} else if (strcmp(func_name, "spawn_on_empty") == 0) {
func = spawn_on_empty;
(*arg).v = strdup(arg_value); // 注意:之后需要释放这个内存

View file

@ -20,6 +20,7 @@ void togglemaxmizescreen(const Arg *arg);
void togglegaps(const Arg *arg);
void tagmon(const Arg *arg);
void spawn(const Arg *arg);
void spawn_shell(const Arg *arg);
void spawn_on_empty(const Arg *arg);
void setlayout(const Arg *arg);
void switch_layout(const Arg *arg);

View file

@ -615,6 +615,32 @@ void centerwin(const Arg *arg) {
resize(c, c->oldgeom, 1);
}
void spawn_shell(const Arg *arg) {
if (!arg->v)
return;
if (fork() == 0) {
// 1. 忽略可能导致 coredump 的信号
signal(SIGSEGV, SIG_IGN);
signal(SIGABRT, SIG_IGN);
signal(SIGILL, SIG_IGN);
dup2(STDERR_FILENO, STDOUT_FILENO);
setsid();
execlp("sh", "sh", "-c", arg->v, (char *)NULL);
// fallback to bash
execlp("bash", "bash", "-c", arg->v, (char *)NULL);
// if execlp fails, we should not reach here
wlr_log(WLR_ERROR,
"mango: failed to execute command '%s' with shell: %s\n",
arg->v, strerror(errno));
_exit(EXIT_FAILURE);
}
}
void spawn(const Arg *arg) {
if (!arg->v)
@ -648,7 +674,7 @@ void spawn(const Arg *arg) {
execvp(argv[0], argv);
// 4. execvp 失败时:打印错误并直接退出(避免 coredump
wlr_log(WLR_ERROR, "dwl: execvp '%s' failed: %s\n", argv[0],
wlr_log(WLR_ERROR, "mango: execvp '%s' failed: %s\n", argv[0],
strerror(errno));
_exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作
}