收到 SIGINT 时将 readline 返回到其原始状态

发布于 2025-01-18 02:21:49 字数 746 浏览 2 评论 0 原文

在bash中,当用户击中 ctrl - c (发送sigint)时,它将读取线带回其原始状态取消搜索/vi-mode/...状态。

我尝试了 unsetstate 宏,但它没有效果,实际上甚至 setState 对readline的状态没有影响,但是 rl_readline_state_state 变量已更改。

在信号处理程序中,我尝试了:

RL_UNSETSTATE(RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_SEARCH|RL_STATE_VIMOTION|RL_STATE_NUMERICARG|RL_STATE_MULTIKEY);

我尝试了 rl_redisplay(),但无效。 请记住,我有:

rl_catch_signals = 0;

我有一个 rl_getc_function 的处理程序。

这是我的代码:

In bash when a user hits ctrl-c (sending SIGINT) it takes back readline to its original state canceling search/vi-mode/... state.

I tried UNSETSTATE macro but it has no effect, actually even SETSTATE has no effect on the state of readline, however the rl_readline_state variable is changed.

In signal handler I tried:

RL_UNSETSTATE(RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_SEARCH|RL_STATE_VIMOTION|RL_STATE_NUMERICARG|RL_STATE_MULTIKEY);

I tried rl_redisplay() but nothing works.
Keep in mind that I have:

rl_catch_signals = 0;

I have a handler for rl_getc_function.

Here is my code:
https://gitlab.com/abellaismail/minishell/-/blob/dev/src/sig_handler.c

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱人如己 2025-01-25 02:21:49

我知道这在某种程度上与 42 有关。
这是我的项目存储库,如果您想进一步了解我找到的解决方案到底如何作品。
假设您的问题适用于提示正在等待命令并且您按 ctrl + C (当在 heredoc 或执行子进程时,行为有点不同),我调用了以下函数:

void    ft_signal_ctrl_c(int sig)
{
    (void)sig;
    write(2, "\n", 1);
    rl_replace_line("", 0);
    rl_on_new_line();
    rl_redisplay();
}

这成功地返回到 shell while (running ) 循环,显示一个新的提示。 errno 也应该单独更新(ctrl+ C 给出 $? = 1)。

I knew it had to do with 42 in some way.
Here's my repo for the project, if you want to look further into how exactly the solution I found works.
Assuming your question applies when the prompt is waiting for a command and you press ctrl + C (when on heredoc or executing childs processes the behaviour is a bit different), I called the following function:

void    ft_signal_ctrl_c(int sig)
{
    (void)sig;
    write(2, "\n", 1);
    rl_replace_line("", 0);
    rl_on_new_line();
    rl_redisplay();
}

This succesfully goes back to the shell while (running) loop, showing a new prompt. errno should be updated separately too (ctrl+ C gives $? = 1).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文