1

这个节目

#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,我就无法保留输入。

4

2 回答 2

1

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

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

第一个问题可以使用更差异化的方式来处理read(). 我应该计算已经读取了多少数据,以及对传递给read().

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

于 2013-03-07T15:51:49.287 回答
0

这是因为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的那些?

于 2013-03-06T13:28:48.820 回答