Scanf 与信号

发布于 2024-08-26 15:25:36 字数 501 浏览 3 评论 0原文

我有一个阻止 SIGINT 的信号,基本上是说“抱歉,你无法退出。\n”

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

当这种情况发生在 scanf 期间时,scanf 将 printf 作为输入。

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

过程:

scanf(“获取东西”) ->用户可以输入内容。-

> SIGINT 发生并发送给我的处理程序。

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

-> Scanf 已经接受了这些废话,正在等待更多的输入。

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

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

I have a signal that blocks SIGINT and basically says "Sorry, you can't quit.\n"

The issue is this can occur during a scanf.

When this occurs during a scanf, scanf takes in the printf as input.

How can I do a printf that will cause scanf to basically hit the enter key automatically. I don't care that I am getting bad input. I just want to programatically finish that scanf with a printf or something else.

Process:

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

-> SIGINT occurs and goes to my handler.

-> Handler says "Blah blah blah" to stdout.

-> Scanf has taken this blah blah blah and is waiting for more input.

How do I make it so that when I return scanf is finished (don't care what it has gathered I just want it to continue without user help).

EDIT: if I send two signals then the scanf terminates. I want to emulate the ending of the scanf somehow programatically.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧情别恋 2024-09-02 15:25:36

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

我有一个阻止 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("获取东西") ->用户可以输入内容。

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

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

-> Scanf 已经接受了这些废话,正在等待更多输入。

你怎么知道 scanf 已经读到了“blah blah blah”?对我来说这似乎非常非常不可能。

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

使用 sigsetjmp()。

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

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

Your question suggests you are confused - or perhaps English is not your native language.

I have a signal that blocks SIGINT and basically says "Sorry, you can't quit.\n"

What you might have is a signal handler that is set to respond to SIGINT. Further, you might be using the 'signal()' function to set the handler - but you should be aiming to use the POSIX standard 'sigaction()' function to set the handler instead.

The issue is this can occur during a scanf.

In context, 'this' is presumably an interrupt signal, typed by the user who wishes to stop your program. Be cautious about stopping people exiting a program with an interrupt signal; if you don't let them do that, they will be more brutal. That might mean they'll generate SIGQUIT (and perhaps a core dump) instead; if you block that too, there are a number of other tricks they can try until they get to the ultimate 'kill -9 pid' which your program will get no chance to react to.

When this occurs during a scanf, scanf takes in the printf as input.

This is confused...you are presumably implying that the output from a 'printf()' statement (presumably the one that says "You can't quit") is then being seen as input to the 'scanf()'? Which seems pretty improbable... It would require a very, very weird setup on the I/O of the process, and I'm still not convinced it can happen.

How can I do a printf that will cause scanf to basically hit the enter key automatically. I don't care that I am getting bad input. I just want to programatically finish that scanf with a printf or something else.

There are several possibilities - it depends in part on the O/S you are using (even if it is POSIX.) I don't use 'scanf()'; I find it too difficult to control. If your system resumes the reads after the interrupt handler returns, then you will have a difficult time. Sometimes, though, 'scanf()' will stop short and return the number of items it has processed. If the 'scanf()' you have does not terminate, then you will need to think about interposing a 'sigsetjmp()' in a function that simply calls 'setjmp()' and then invokes your function that calls 'scanf()'. Then your signal handler can use 'siglongjmp()' to return to that intermediate function:

sigjmp_buf trap;

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

Your description continues:

Process:

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

-> SIGINT occurs and goes to my handler.

-> Handler says "Blah blah blah" to stdout.

-> Scanf has taken this blah blah blah and is waiting for more input.

How do you know that scanf has read the 'blah blah blah'? It seems very, very improbable to me.

How do I make it so that when I return scanf is finished (don't care what it has gathered I just want it to continue without user help).

Use sigsetjmp().

EDIT: if I send two signals then the scanf terminates. I want to emulate the ending of the scanf somehow programmatically.

This is what indicates that you are using 'signal()' to set your signal handler and not 'sigaction()'. With 'signal()', when the interrupt occurs, the signal handler is set back to the default. With 'sigaction()', you have to request that behaviour; by default, the received signal (SIGINT) is blocked for the duraction and the signal handler remains in effect. If a second interrupt occurs while the first is running, the second is held up until the first handler returns (at which point the handler will be re-entered).

一张白纸 2024-09-02 15:25:36

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

这是假设 QNX 符合 POSIX 读取标准,并且您没有 scanf 的源代码进行检查。

Don't use scanf as its buffering or retry code may get in the way. If you use a read(2) call it should return -1 with an errno of EINTR. Scanf may see that error and retry the read. You can always sscanf the data from the raw read.

This is assuming that QNX is POSIX compliant for read and you don't have the source for scanf for inspection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文