0

I have this code:

#include <stdio.h> #include <signal.h> void signal_handler(int signal) { printf("Caught signal in CHILD.\n"); } int main(void) { int s; signal(SIGTSTP, signal_handler); while(1){ printf("%s@%s/# ",getlogin(),get_current_dir_name()); scanf("%d",&s); } return 0; } 

when i run the code it prints:

something: ^ZCaught signal in CHILD. 

As far i understand that the scanf doesn't execute when i press the ctr-z. Although after the printf inside my function it goes straight to the scanf, waits for input and then starts the loop again.Is there any way to avoid scanf when i press ctr-z and start the while loop again? I tried something like that

void signal_handler(int signal) { printf("Caught signal in CHILD.\n"); printf("%s@%s/# ",getlogin(),get_current_dir_name()); } 

but it didn't work. After the second printf goes straight to the scanf, waits for input and then starts the loop again. Can i, somehow, start the loop again?

3
  • I'm not getting you. The code do exactly what you wrote. When you press the first time ctrl-z scanf is skypped and loop restarts. Commented Oct 9, 2015 at 14:32
  • That's my problem! Scanf doesn't skipped! and i can't understand why... Commented Oct 9, 2015 at 14:37
  • The worst code could be adding exit(1) to your signal handler. I'll post an example Commented Oct 9, 2015 at 14:44

2 Answers 2

2

The signal handler is interrupting scanf during its read of STDIN. However, because of the way you set signal disposition, the read system call restarts immediately upon return of the signal handler. That's why you are "stuck" in the scanf rather than back at the top of your loop.

One important thing you can do is to use sigaction rather than signal. This will force you to specify the behavior of interrupted calls: restart them or not?

The next thing to do is to limit your signal handlers to functions that are async-signal-safe, lest you risk misery.

As an aside, another change to make is to give us all the required includes (<unistd.h>?) and defines (_GNU_SOURCE ?) to make your program work.

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

Comments

0

As commented the worst solution should be:

#include <stdio.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> void signal_handler(int signal) { printf("Caught signal in CHILD.\n"); exit(1); } int main(void) { int s; signal(SIGTSTP, signal_handler); while(1){ printf("test\n"); scanf("%d",&s); } return 0; } 

Better solution

#include <stdio.h> #include <signal.h> static volatile int keepRunning = 1; void signal_handler(int signal) { printf("Caught signal in CHILD.\n"); keepRunning = 0; } int main(void) { int s; signal(SIGTSTP, signal_handler); while(keepRunning){ printf("test\n"); scanf("%d",&s); } return 0; } 

EDIT after comments

#include <stdio.h> #include <signal.h> static volatile int skipPrintf= 1; void signal_handler(int signal) { printf("Caught signal in CHILD.\n"); skipPrintf= 1; } int main(void) { int s; signal(SIGTSTP, signal_handler); while(1){ if (skipPrintf == 0) { printf("test\n"); } else { skipPrintf = 0; } scanf("%d",&s); } return 0; } 

7 Comments

Well with exit the program terminates. I want to start over again the while loop. I want to after the ctr-z is pressed to print again test,as your example, and then the scanf waits for input. Unbelievable!!! i've never seen someone to use volatile! Thanks for your help
In this case volatile is mandatory, because of is keepRunning is modified in t handler and main.
@Csd I really not getting you. The code you posted exec exactly as you want. After a ctrl-z redo printf and go to scanf.
But i don't want to go to the scanf! i Want to start the while loop again from the start.
@Csd Is what your posted code do. printf --> wait for scanf -->press ctrl-z --> go to signal handler---> printf egain-->scanf
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.