You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GNU Readline额外提示符异常问题的修复方案咨询

问题描述

使用GNU Readline库编写类Shell程序时,遇到提示符处理Bug:通过^D退出here doc后,在主提示符按下^C,会意外出现额外提示符。复现步骤如下:

$ <<a    # 开始here doc
>        # 用户输入^D退出here doc
$ ^C     # 用户在主提示符输入^C
$        # 意外出现的额外提示符
$

简化复现代码:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

volatile sig_atomic_t g_sig;

void handle_sigint(int sig) {
    g_sig = sig;
}

int readline_hook(void) {
    if (g_sig == SIGINT) {
        rl_replace_line("", 0);
        rl_on_new_line();
        rl_redisplay();
        rl_done = 1;
    }
    return 0;
}

int main(void) {
    char *line;
    signal(SIGINT, handle_sigint);
    rl_event_hook = readline_hook;
    while (1) {
        g_sig = 0;
        line = readline("$ ");
        free(line);
    }
}

修复方案

问题根源在于readline_hook中调用rl_redisplay()会触发Readline重复绘制提示符,后续循环再次调用readline("$ ")时就会出现额外提示符;同时原始信号处理逻辑的可靠性不足,终端状态未正确重置。

具体修复步骤

  1. 替换signal为sigaction,保证信号处理的跨平台稳定性
  2. 在SIGINT处理函数中直接输出换行,替代rl_redisplay(),避免重复绘制
  3. 移除readline_hook中的rl_redisplay()调用,处理完信号后重置标记位
  4. 处理readline()返回NULL的EOF场景(用户输入^D),手动输出换行维护终端状态

修改后的代码

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <readline/readline.h>

volatile sig_atomic_t g_sig;

void handle_sigint(int sig) {
    g_sig = sig;
    // 直接输出换行,避免Readline重复处理提示符
    write(STDOUT_FILENO, "\n", 1);
}

int readline_hook(void) {
    if (g_sig == SIGINT) {
        rl_replace_line("", 0);
        rl_on_new_line();
        rl_done = 1;
        // 重置信号标记,防止钩子重复触发
        g_sig = 0;
    }
    return 0;
}

int main(void) {
    char *line;
    struct sigaction sa;
    sa.sa_handler = handle_sigint;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sigaction(SIGINT, &sa, NULL);
    
    rl_event_hook = readline_hook;
    while (1) {
        g_sig = 0;
        line = readline("$ ");
        // 处理^D触发的EOF情况
        if (line == NULL) {
            write(STDOUT_FILENO, "\n", 1);
            continue;
        }
        free(line);
    }
}

内容的提问来源于stack exchange,提问作者kemizuki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:42:43