Scanf with Signals - c++

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.

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

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.

Related

why putting \n alters the order of execution

while I am trying to code in c for zombie process simulation ,I am getting alteration in output due to putting of \n in printf statements:
code1:
main()
{
int id;
id=fork();
if(id>0)
{
printf("Parent will sleep");//pf1//
sleep(5);
//system("ps -u");
}
if(id==0)
printf("I am child");//pf2//
}
output:
I am childParent will sleep
but while putting \n in pf1 or pf2 the order of execution of statements changes.what is the reason behind \n altering the order ?
stdout is line-buffered.
When you printf something to stdout, the library buffers this content up until a newline character is observed. At that point, the buffer is flushed, and will finally be displayed on your console. If you don't print a newline character, the data may stay in the buffer indefinitely, and you won't see it until the next time you print a newline character, or the process exits.
To ensure that your prints are always visible immediately, you can do one of these things:
fprintf(stderr, ...) instead. stderr is not buffered; data written to it will be visible immediately.
fflush(stdout) - Manually force the stream to be flushed immediately.
Update: Note that none of this actually matters, because of the inherent race condition involved. You have no control over whether the parent or child process executes first, and which one's data will be written to the console first. You could even possibly see the output interleaved as they both try to print at the same time. (Thanks to jschultz410 for pointing out my foolishness.)

C++ Primer 1.4.4 — Importance of EOF and how to write in a code that will end without EOF?

Referring to two questions:
Incorrect output from C++ Primer 1.4.4
Confused by control flow execution in C++ Primer example
My question is answered in both of those posts, but I want to delve further.
First, I know this is only the beginning, but let's say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a EOF? I can't expect someone running my program to know that they need to hit Control-Z.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
Also one guy in those questions somewhat answered the importance of EOF, but how come the program doesn't even post the final cnt - 1?
Let's say I do the numbers 10 10 10 20 20 20. Without EOF, this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
lets say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a eof? I can't expect someone running my program to know that they need to hit ctrl + z.
You could either tell the user explicitly to do a specific action to end input or the design of the window itself could tell the user the information implicitly. For instance, a dialog box could ask the user to enter input and click an OK button when done.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
It seems like you would rather use a newline character to terminate your input. An example of this usage could be std::getline. Instead of writing
while (std::cin >> val)
you could instead use
std::string line;
if (std::getline(std::cin,line))
and assume that your user's input only consists of one line of values. There are plenty of other ways to similarly achieve this task depending on how you want to constrain the user's input.
Let's say I do the numbers 10 10 10 20 20 20. WIthout eof this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
Without the eof your program is still executing the while (std::cin >> val) loop since std::cin >> val has not yet received invalid input.
Since the line
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
occurs after that while loop finishes execution, you don't (yet) see any information about the three 20's in the input.
When you are reading a sequence of inputs you'll need some indication when your down. That could be a sentinel value ("enter 999 to stop reading"; you'd need to detect that while reading), an invalid input ("enter X to stop reading"; when reading an int the value X is illegal and causes the stream to got into failure mode, i.e., have std::ios_base::failbit set), or the more conventional "there isn't anything more to read". For a file, the last conditions is straight forward. When reading data from the console you'll either need to teach people how to terminate the input or you'll need to use a different approach.
If you want to intercept any keypressed and react on them directly you may do so, too. You could, e.g., use ncurses and control your input via that. You could also set the concole to non-buffering (on POSIX systems using tcgetattr() and tcsetattr() to clear the ICANON flag) and deal directly with all key presses to decide whether you want to continue reading or not.
Although I'm certainly up to doing fancy I/O stuff I normally don't bother: users will understand the "end of input" character and just deal with it. That is, my input normally looks something like this:
while (in >> whatever_needs_to_be_read) { ... }
... or, if the input is genuinely line oriented
for (std::string line; std::getline(in, line); ) { ... }
The function doing this input will then be called with a suitable std::istream which may be std::cin although I have typically some way to also read from a file (in addition to the shell-privided input redirection).
BTW, despite some indications in the questions referenced, "EOF" is not a character being read. It is a character entered, though (normally). ... and it is quite conventional to "know" the end of input character (on POSIX systems a ctrl-D and on Windows a ctrl-Z). You can use other indicators, e.g., the "interrupt" (ctrl-C) but that takes more work and doesn't integrate nicely with stream. To use the interrupt chacter you'd need to setup a signal handler for SIGINT and deal with that. One slightly annoying part of doing so is that if you get it wrong you'll need to find a different way to kill the program (e.g. on POSIX using ctrl-Z to put the process to sleep and kill it via a harsher signal).

Implementing a printer spooler

We have an assignment in which we have to implement a printer spooler using linked lists. I have used the list from STL to implement everything. I can get the program to send the print command and maintain status of documents. The problem is I don't know how to mimic/send a dummy print command so the document gets printed. If I use Sleep() there is a delay in the whole program.while I want printing on backhand and others users to have access to the program.
Any help will be appreciated regarding my problem thanks.
In a REAL print spooler, either there are multiple threads (or in Unix, maybe a fork) or the system uses a "wait for several objects" type approach, and when there is something to print, a portion of the document is sent to the printer, set up so that when that portion is "consumed", a waitable object is "ready". Then the spooler waits for something to happen (either a new job or the printed). When the wait is completed, it determines what happened. If it's a new print job, queue it, if it's "some printing completed", it checks if that's the last of the printing and completes the job, or sends more stuff to the printer.
In pseudocdoe it may look something like this:
for(;;)
{
what = wait_for_work();
switch (what)
{
case new_job:
add_new_job();
break;
case print_write_done:
if (document_complete)
remove_current_job();
else
send_more_from_current_job();
break;
case spooler_terminate:
exit(0);
default:
print_error_message();
}
}
Obviously, without seeing your code, it's hard to say how you should implement it. But one could have a timer to simulate the "document being printed in small chunks", say, 10KB is consumed every 100ms, for example.

Interrupt running program and save data

How to design a C/C++ program so that it can save some data after receiving interrupt signal.
I have a long running program that I might need to kill (say, by pressing Ctrl-C) before it finished running. When killed (as opposed to running to conclusion) the program should be able to save some variables to disk. I have several big Linux books, but not very sure where to start. A cookbook recipe would be very helpful.
Thank you.!
to do that, you need to make your program watch something, for example a global variable, that will tell him to stop what it is doing.
For example, supposing your long-running program execute a loop, you can do that :
g_shouldAbort = 0;
while(!finished)
{
// (do some computing)
if (g_shouldAbort)
{
// save variables and stuff
break; // exit the loop
}
}
with g_shouldAbort defined as a global volatile variable, like that :
static volatile int g_shouldAbort = 0;
(It is very important to declare it "volatile", or else the compiler, seeing that no one write it in the loop, may consider that if (g_shouldAbort) will always be false and optimize it away.)
then, using for example the signal API that other users suggested, you can do that :
void signal_handler(int sig_code)
{
if (sig_code == SIGUSR1) // user-defined signal 1
g_shouldAbort = 1;
}
(you need to register this handler of course, cf. here.
signal(SIGUSR, signal_handler);
Then, when you "send" the SIGUSR1 signal to your program (with the kill command for example), g_shouldAbort will be set to 1 and your program will stop its computing.
Hope this help !
NOTE : this technique is easy but crude. Using signals and global variables makes it difficult to use multiple threads of course, as other users have outlined.
What you want to do isn't trivial. You can start by installing a signal handler for SIGINT (C-c) using signal or sigaction but then the hard part starts.
The main problem is that in a signal handler you can only call async-signal-safe functions (or reentrant functions). Most library function can't be reliably considered reentrant. For instance, stdio functions, malloc, free and many others aren't reentrant.
So how do you handle this ? Set a flag in you handler (set some global variable done to 1) and look out for EINTR errors. It should be safe to do the cleanup outside the handler.
What you are trying to do falls under the rubric of checkpoint/restart.
There's several big problems with using a signal-driven scheme for checkpoint/restart. One is that signal handlers have to be very compact and very primitive. You cannot write the checkpoint inside your signal handler. Another problem is that your program can be anywhere in its execution state when the signal is sent. That random location almost certainly is not a safe point from which a checkpoint can be dropped. Yet another problem is that you need to outfit your program with some application-side checkpoint/restart capability.
Rather than rolling your own checkpoint/restart capability, I suggest you look into using a free one that already exists. gdb on linux provides a checkpoint/restart capability. Another is DMTCP, see http://dmtcp.sourceforge.net/index.html .
Use signal(2) or sigaction(2) to assign a function pointer to the SIGINT signal, and do your cleanups there.
Make your you enter only once in your save function
// somewhere in main
signal( SIGTERM, signalHandler );
signal( SIGINT, signalHandler );
void saveMyData()
{
// save some data here
}
void signalHandler( int signalNumber )
{
static pthread_once_t semaphore = PTHREAD_ONCE_INIT;
std::cout << "signal " << signalNumber << " received." << std::endl;
pthread_once( & semaphore, saveMyData );
}
If your process get 2 or more signals before you finish writing your file you'll save weird data

C - printf and scanf - How do I terminate input?

I am working on a simple application written in C. I am working in a Unix environment.
My application is doing some simple I/O. I use printf to prompt the user for some input and then use scanf to get that input.
The problem is, I don't know how to tell my application that I am ready to proceed after entering in a value. Typing 'enter' provides a newline '\n' which makes sense. Control-d does allow scanf to capture my input but seems to ignore any subsequent scanf instructions.
Can someone help me out?
printf("Enter name\n");
scanf("%s",input);
printf("%s",input);
printf("enter more junk\n")
scanf("%s",morestuff); /* cntrl+d skips this*/
Check the return value from scanf(). Once it has gotten EOF (as a result of you typing control-D), it will fail each time until you clear the error.
Be cautious about using scanf(); I find it too hard to use in the real world because it does not give me the control over error handling that I think I need. I recommend using fgets() or an equivalent to read lines of data, and then use sscanf() - a much more civilized function - to parse the data.
See also a loosely related question: SO 3591642.
[EDIT: This answer is incorrect, as I stated below, I'm learning as well]
Have you tried CTRL-Z?
That sends EOF to scanf, which, according to its man page, should make scanf move to the next field. As you've entered only a string as the input format, that should terminate the scanf.
I can't test this right now, but you can give it a shot.
Man page is here:
http://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.scanf.html