【问题标题】:Catching SIGINT signal to terminate a custom shell捕获 SIGINT 信号以终止自定义 shell
【发布时间】:2015-09-13 12:36:51
【问题描述】:

希望你能帮我解决这个问题。

对于学校,我必须将 Ctrl+C 转换为不会关闭 shell 的命令,但他通过 printf() 提醒我必须键入 exit 才能关闭 shell。我什至不知道从哪里开始。

非常感谢。

【问题讨论】:

  • 这在很大程度上取决于您的操作系统。对于 POSIX 系统(例如 Linux 或 OSX)搜索 SIGINT,在 Windows 上搜索 SetConsoleCtrlHandler
  • @JoachimPileborg: signal()+SIGINT 也适用于 Windows。 GUI 应用程序除外。
  • 如果你在谷歌上搜索,你会更快找到答案。
  • 我会吗? :D 我应该查什么?

标签: c signals system-calls


【解决方案1】:

Ctrl+C 向正在运行的进程发送一个中断信号(SIGINT)。您可以使用 signal() 来捕获 SIGINT,如下所示:

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

 void sigint_handler(int sig)
 {
   printf("Type exit to close the shell!\n");
 }


  int main()
  {
    signal(SIGINT, sigint_handler);

    /*Your code should replace the while loop.*/
    while(1)
    {
        printf("Running!\n");
        getchar();
    }

    return 0 ;
  }

【讨论】:

  • Tha POSIX manual for signal() 说“...新应用程序应该使用 sigaction() 而不是 signal()。
  • 在像这样异步调用的信号处理程序中可以执行的操作受到严格限制。引用标准:“[T]如果信号处理程序调用标准库中的任何函数,而不是 abort 函数、_Exit 函数或第一个参数等于与导致处理程序调用的信号相对应的信号编号。"
【解决方案2】:

这是使用sigaction 处理SIGINT 的简单实现,它将在posix 系统上工作。为简洁起见,省略了错误检查。链接的手册应该解释sigaction

基本上程序循环通过一个无限循环并在用户类型退出时中断。使用write,因为您不能在信号处理程序中使用 printf。有关可以在信号处理程序中安全使用的函数列表,请参阅 signal manual

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

char s[]="Type 'exit' to terminate\n";

void int_handler (int signum)
{
  write(fileno(stdin), s, sizeof s - 1);
}

int main (void)
{
  char str[256];
  struct sigaction sh;

  sh.sa_handler = int_handler;
  sigemptyset (&sh.sa_mask);
  sh.sa_flags = 0;
  sigaction (SIGINT, &sh, NULL);
  printf("%s", s);

  while(1) {
    fgets(str, sizeof str, stdin);
    char *p = strchr(str, '\n');
    if(p) *p = 0;
    if(!strcmp(str, "exit")) {
      printf("Exiting on request...");
      break;
    }
  }
  return 0;
}

【讨论】:

  • 有没有更简单的方法来达到同样的目标?
  • 我发布的是捕获 SIGINT 的幼稚实现。没有更简单的方法!只需阅读链接页面中信号的工作原理即可。
【解决方案3】:

当您谈论从 shell 执行此操作时,您可能想要:

$ trap "echo Please type \'exit\' to close the shell." SIGINT
<Ctrl-C>
Please type 'exit' to close the shell.
$

这指定了在捕获列出的信号时执行的命令(trap 命令也可以捕获其他信号;SIGINT 是由Ctrl-C 生成的信号)。 \' 保护引号不被 shell 解释。

【讨论】:

  • @Pino,那么显然,您所指的外壳是您自己编写的外壳,是吗?接收中断信号的程序(作为用户键入 Ctrl-C 的结果)必须以一种或另一种方式提供自己的处理程序,如果它要产生非默认响应。
  • 对不起,我把“关闭外壳”理解为交互式的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-05
相关资源
最近更新 更多