【问题标题】:CTRL-C handler not working properlyCTRL-C 处理程序无法正常工作
【发布时间】:2013-03-06 13:10:55
【问题描述】:

这个程序

#include <stdio.h> 
#include <signal.h>
#include <stdlib.h>
#include <windows.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

void INThandler(int);             

int  main(void)
{
   signal(SIGINT, INThandler);    

   char data[128];

   int n;

   while((n=read(0, data, 128)) > 0)
   {
   if(data[n] = '\n') break;
   }

   data[n] ='\0';

   printf("%s", data);

   return 0;
}

void  INThandler(int sig)
{
     char  c;

     signal(sig, SIG_IGN);             
     printf("OUCH, did you hit Ctrl-C?\n"    
            "Do you really want to quit? [y/n] ");
     c = getchar();                     
     if (c == 'y' || c == 'Y')          
         exit(0);                      
     else
      signal(SIGINT, INThandler);
}

不处理 ctrl-c,但在该输入处终止。 如果我替换处理程序安装和返回之间的所有内容

while (1)                          
Sleep(1);

处理函数被调用并且可以工作,但我想在其中有 read()。

编辑:回顾这个程序,我注意到我有

if(data[n] = '\n') break;

我写了'='而不是'==',但是使用后者,它不能正常工作,我不明白为什么。不应该是检测'\n'的比较吗? 另外,我弄乱了缓冲区,但是如果按 CTRL-C,我就无法保留输入。

【问题讨论】:

    标签: c windows-7 handler interrupt


    【解决方案1】:

    示例代码没有考虑两个问题:

    1. read() 如果它的进程接收到一个信号将中止它的工作(见man 2 read
    2. 仅保证少数函数可以从信号处理函数中保存调用(请参阅man 7 signal)。 printf()getch()属于这组“保存”功能。

    第一个问题可以使用更不同的方式来处理read() 返回的值。我应该计算已经读取了多少数据,以及对传递给 read() 的缓冲区的一些智能调整。

    关于第二个问题,read()write() 是执行信号处理程序的输入/输出的选择函数,因为上面提到的手册页将这些函数列为“保存”函数。

    【讨论】:

      【解决方案2】:

      这是因为您使用的read(2) 的实现不允许这样做。这是我编译您的程序,执行它并按^C时得到的:

      $ ./program
      ^COUCH, did you hit Ctrl-C?
      Do you really want to quit? [y/n] y
      $
      

      或者如果我回答 n 并输入一些数据:

      $ ./program
      ^COUCH, did you hit Ctrl-C?
      Do you really want to quit? [y/n] n
      test
      test
      $
      

      由于read(2) 是系统调用,它取决于您使用的系统。我使用 Linux (3.2.0-4-686-pae),它的行为正确。也许您应该考虑将scanf(3)fread(3)stdio(3) 一起用于您正在使用的平台(我认为是win32)?或者也使用不同的实现,比如来自 CygwinMinGW 的那些?

      【讨论】:

      • 我明白了,所以这取决于 SO。到目前为止,我使用 Windows 并在 Unix 上进行测试没有任何问题。谢谢。
      猜你喜欢
      • 2014-10-23
      • 2015-07-02
      • 2014-07-27
      • 2013-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 2016-05-06
      相关资源
      最近更新 更多