【问题标题】:Hide ^C pressing ctrl-c in C在 C 中按 ctrl-c 隐藏 ^C
【发布时间】:2017-03-02 18:42:21
【问题描述】:

我正在创建自己的 shell,我想在任何 Linux 发行版上的任何用户按 ctrl+c 时禁用 ^C。

我不需要处理信号 SIGINT,我已经这样做了,因为不要在 ctrl+c 上停止程序。我只想知道如何隐藏这两个字符^C

在我的程序开始时是否有任何函数可以调用或设置环境变量?

编辑

  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)

【问题讨论】:

  • 您需要在终端上禁用回显(但这也意味着您需要自己处理来自输入的回显)。
  • 怎么样,我不确定
  • 我想我可以用 execv 和 stty -echoctl
  • @Olaf 是的,有办法。
  • execve("stty", cmd_args, env);使用 cmd_args (-echoctl) 不起作用,知道吗?

标签: c shell exit


【解决方案1】:

^C 来自 Linux 终端驱动程序的回显

这是一个 C 语言示例程序。它首先禁用保存当前设置,并在程序退出时注册atexit 处理程序以恢复设置,然后禁用标准输入终端上的回显。然后它进入一个无限的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) {};
}

【讨论】:

  • 好的,谢谢你,但这是一个学校项目,我不能使用你目前正在使用的一些功能。你认为 stty 可以与 execv 一起使用吗
  • ...不能使用我正在使用的某些功能?!这是我听过的最奇怪的事情!那么这是什么学校项目呢?是的 stty 会工作......并且 stty 会调用这个相同的函数
  • 我知道这很愚蠢。但是我们禁止所有功能,除非他们指定某人被授权。我的stty有问题,它显示一个正方形,像不可写字符
  • 如果您只能使用某些功能,请在您的原始问题中列出所有这些功能来帮助我们。
【解决方案2】:

运行stty -echoctl 应该隐藏它。详情请见man stty

【讨论】:

  • 我应该在运行时执行它吗?
  • execve("stty", args, env);不起作用。不好的答案
  • “不工作”不是一个有用的说法。当你尝试时发生了什么?另外,请注意 execve 不会搜索您的路径,因此您需要完全限定它或使用 execvp 之类的包装器。
  • 我应该在做之前 fork() 吗?即使使用 /bin/stty 它也不起作用
  • 是的,因为 exec 系列函数替换了当前进程,而不是创建一个新进程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
相关资源
最近更新 更多