隐藏^C在C中按ctrl-c

icomxhvb  于 2023-06-21  发布在  其他
关注(0)|答案(3)|浏览(172)

我正在创建自己的shell,我想在任何Linux发行版上的任何用户按下ctrl + c时禁用^C。
我不需要处理信号SIGINT,我已经在ctrl + c上做了不要停止程序。我只是想知道如何隐藏这两个字符^C
在我的程序开始的时候,有没有什么函数需要调用或者env变量需要设置?
编辑

int a = fork();
  if (!a) {
    char *cmd[] = {"/bin/stty", 0 };
    char *cmd_args[] = {" ", "-echoctl", 0};
    execve(cmd[0], cmd_args, env);
  }

我试过了。它在ctrl-c上删除了我的^C,但它仍然显示一个方形字符,就像字符不能显示一样。好像是EOT(003 ascii)

x6h2sr28

x6h2sr281#

^C来自Linux中终端驱动程序上的echo
这里有一个C语言的示例程序。它首先禁用保存当前设置,并注册一个atexit处理程序以在程序退出时恢复设置,然后禁用标准输入端的echo。然后它进入一个无限的while循环。现在,当您在终端上输入任何内容时,nothing 都不会显示,甚至^C也不会显示。
shell使用的技巧是它们 * 完全取代 * 终端上的输入处理,关闭规范输入处理,一次阅读一个字符的标准输入,并自己处理回显-这需要比Stack Overflow答案更多的代码。

#include <termios.h>
#include <unistd.h>
#include <stdlib.h>

struct termios saved;

void restore(void) {
    tcsetattr(STDIN_FILENO, TCSANOW, &saved);
}

int main() {
    struct termios attributes;

    tcgetattr(STDIN_FILENO, &saved);
    atexit(restore);

    tcgetattr(STDIN_FILENO, &attributes);
    attributes.c_lflag &= ~ ECHO;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &attributes);

    printf("Entering the loop\n");
    while(1) {};
}
nwsw7zdq

nwsw7zdq2#

运行stty -echoctl应该会隐藏它。请参阅man stty了解更多详细信息。

sbdsn5lh

sbdsn5lh3#

可以使用ANSI escape codes删除^C字符。在处理SIGINT信号的函数中,打印将光标向左移动两次的字符,然后删除右边直到行尾的所有字符。
下面的示例适用于macOS和Raspberry Pi OS。
在Windows上不需要这个技巧,因为按ctrl+c是无声的。

/**
    remove_ctrl_c.c
    gcc remove_ctrl_c.c -o remove_ctrl_c && ./remove_ctrl_c

    Remove the characters ^C with ANSI escape codes.
    (see https://en.wikipedia.org/wiki/ANSI_escape_code)

    \b     : Move cursor one character on the left.
    \b     : Idem
    \033[K : Delete all the characters on the right of
             the cursor until the end of the line.
             You can also use two spaces if you prefer,
             but they will be present in the output although
             they are not visible.
    \n     : Add a new line. This is optional,
             but if you remove it and some characters
             are printed on the last line, the terminal
             will add an extra % character to indicate
             that the new line character was absent.

    Note that, as the printf command is buffered,
    we need to use the fflush command before the end
    of the program to force stdout to be updated.
*/

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

volatile sig_atomic_t KEYBOARD_INTERRUPT = 0;

void handleSignal(int signal)
{
    KEYBOARD_INTERRUPT = 1;
}

int main()
{
    signal(SIGINT, handleSignal);
    printf("Remove ^C on exit!");
    fflush(stdout);
    while (!KEYBOARD_INTERRUPT)
    {
    }
    printf("\b\b\033[K\n");
    fflush(stdout);
    return 0;
}

相关问题