1

我有一个阻止 SIGINT 的信号,基本上说“对不起,你不能退出。\n”

问题是这可能在 scanf 期间发生。

如果在 scanf 期间发生这种情况,scanf 会将 printf 作为输入。

我怎样才能做一个 printf ,这将导致 scanf 基本上自动按回车键。我不在乎我得到不好的输入。我只想用 printf 或其他东西以编程方式完成该 scanf 。

过程:

scanf("get stuff") -> 用户可以输入东西。

-> SIGINT 发生并转到我的处理程序。

-> 处理程序对标准输出说“Blah blah blah”。

-> Scanf 已经接受了这个 blah blah blah 并且正在等待更多输入。

我如何做到这一点,以便当我返回 scanf 时完成(不在乎它收集了什么,我只是希望它在没有用户帮助的情况下继续)。

编辑:如果我发送两个信号,则 scanf 终止。我想以某种方式以编程方式模拟 scanf 的结尾。

4

2 回答 2

1

您的问题表明您很困惑 - 或者英语可能不是您的母语。

我有一个阻止 SIGINT 的信号,基本上说“对不起,你不能退出。\n”

您可能拥有的是一个设置为响应 SIGINT 的信号处理程序。此外,您可能正在使用 'signal()' 函数来设置处理程序 - 但您应该旨在使用 POSIX 标准 'sigaction()' 函数来设置处理程序。

问题是这可能在 scanf 期间发生。

在上下文中,“this”可能是一个中断信号,由希望停止程序的用户键入。小心使用中断信号阻止人们退出程序;如果你不让他们那样做,他们会更加残暴。这可能意味着他们将生成 SIGQUIT (可能还有核心转储);如果你也阻止它,他们可以尝试许多其他技巧,直到他们达到最终的“kill -9 pid”,你的程序将没有机会做出反应。

如果在 scanf 期间发生这种情况,scanf 会将 printf 作为输入。

这很困惑......您大概是在暗示“printf()”语句的输出(大概是说“您不能退出”的语句)然后被视为“scanf()”的输入?这似乎不太可能......它需要在进程的 I/O 上进行非常非常奇怪的设置,我仍然不相信它会发生。

我怎样才能做一个 printf ,这将导致 scanf 基本上自动按回车键。我不在乎我得到不好的输入。我只想用 printf 或其他东西以编程方式完成该 scanf 。

有几种可能性 - 它部分取决于您使用的操作系统(即使它是 POSIX。)我不使用 'scanf()';我觉得太难控制了。如果您的系统在中断处理程序返回后恢复读取,那么您将遇到困难。但有时,'scanf()' 会停止并返回它已处理的项目数。如果你的'scanf()'没有终止,那么你需要考虑在一个简单地调用'setjmp()'的函数中插入一个'sigsetjmp()',然后调用你调用'scanf()'的函数. 然后您的信号处理程序可以使用“siglongjmp()”返回到该中间函数:

sigjmp_buf trap;

int intermediary(int argument)
{
    if (sigsetjmp(trap) == 0)
    {
         function_calling_scanf(argument);
         return 0;  // Success
    }
    // Report failure
    return -1;
}

您的描述继续:

过程:

   scanf("get stuff") -> User is able to enter stuff in.

-> SIGINT 发生并转到我的处理程序。

-> 处理程序对标准输出说“Blah blah blah”。

-> Scanf 已经接受了这个 blah blah blah 并且正在等待更多输入。

你怎么知道 scanf 读过'blah blah blah'?这对我来说似乎非常非常不可能。

我如何做到这一点,以便当我返回 scanf 时完成(不在乎它收集了什么,我只是希望它在没有用户帮助的情况下继续)。

使用sigsetjmp().

编辑:如果我发送两个信号,则 scanf 终止。我想以某种方式以编程方式模拟 scanf 的结尾。

这表明您正在使用“signal()”来设置信号处理程序,而不是“sigaction()”。使用“signal()”,当中断发生时,信号处理程序被设置回默认值。使用“sigaction()”,您必须请求该行为;默认情况下,接收到的信号 (SIGINT) 在持续时间内被阻塞,并且信号处理程序保持有效。如果在第一个中断运行时发生第二个中断,则第二个中断将一直保持到第一个处理程序返回(此时将重新进入处理程序)。

于 2010-03-25T04:24:34.033 回答
0

不要使用 scanf ,因为它的缓冲或重试代码可能会妨碍。如果您使用read(2)调用,它应该返回 -1 并带有 EINTR 的 errno。Scanf 可能会看到该错误并重试读取。您始终可以从原始读取中扫描数据。

这是假设 QNX 是 POSIX 兼容的读取,并且您没有用于检查的 scanf 源。

于 2010-03-25T03:21:14.863 回答