1

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.

2
  • "When this occurs during a scanf, scanf takes in the printf as input." is a strange statement, did you mean this? Have you played with file descriptors or pipes that you haven't explained? In the normal C startup, stdin and stdout are quite detached. Commented Mar 25, 2010 at 3:24
  • I'm not sure if it goes into the scanf, but if I enter data into the scanf after, it never works. I dont want it to come back to the scanf statement at all and thats my problem. Commented Mar 25, 2010 at 3:43

2 Answers 2

1

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).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the effort. My apologies. It's very late and I tried to half ass my question. I resolved it by removing scanf and resorting to fgets.
0

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.

3 Comments

The issue is I am using functions I have NO choice in using. It is POSIX compliant.
You were onto the right track. I am never using scanf again. I had to use something along this line, except I used fgets.
Not using scanf() is a good idea; using fgets() is a lot more sensible in my experience.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.