How to capture ctrl+S and ctrl+Q in C - c

I am trying to change the default behaviour of the terminal when I press ctrl+S (freeze) and ctrl+Q (unfreeze). My code is:
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
void sig_handler(int signum){
printf("\nInside handler function\n");
}
int main(){
signal(SIGSTOP, sig_handler);
for(int i=1;;i++){
printf("%d : Inside main function\n",i);
sleep(1);
}
return 0;
}
Before I run the code I disable the default behaviour by giving this command: stty -ixon -ixoff.
The problem is that when I run the code and press ctrl+S nothing happens, the characters ^S just get printed on the screen. Can I have some guidance oh how to do this or what to look for more information? Thanks.

1 The signals SIGKILL and SIGSTOP cannot be caught or ignored
2 maybe using tcsetattr is a way for resolving your problem. modify characters for VSTART/VSTOP, then process ctrl+S by your program

Related

Why pause() function prevents seeing console output in C?

I'm a little bit confused how does the function pause() works in the sense of calling order. For example:
int main(){
printf("Start\n");
pause();
printf("Finish\n");
}
I was expecting to get output "Start" before pause, but program just immediately pauses instead. Please, explain why. Thanks in advance.
Your terminal emulator doesn't apparently flush standard output on every newline. You can manually flush it with fflush(stdout) if you want to see the output immediately:
int main(){
printf("Start\n");
fflush(stdout);
pause();
printf("Finish\n");
}

Interrupted system call in C

I want to make my program sleep upto 10 seconds even the signal is occured. So, I tried the following program.
Program:
#include<stdio.h>
#include<signal.h>
#include<errno.h>
int main()
{
printf("PID: %d\n",getpid());
int unslept=10;
while(unslept>0){
unslept=sleep(unslept);
if(errno==EINTR)
continue;
}
return 0;
}
Output:
$ ./a.out
PID: 18935
User defined signal 1
$
I expect the above program will execute 10 seconds even the signal is interrupted. I exeperiment it like, in one terminal I
executed this program. And using another terminal using kill command I sent the SIGUSR1 signal to this process. But, the same problem
occurs. Once the signal is passed, the program terminates. So, is there any way to execute my program upto 10 seconds without affecting
any signal.
You can ignore the signal. See the below example, in that example, if the SIGUSR1 signal is interrupted, it just ignore the signal using the SIG_IGN.
#include<stdio.h>
#include<signal.h>
int main(void)
{
if (signal(SIGUSR1, SIG_IGN) == SIG_ERR)
perror("SIGUSR1");
sleep(30);
}
You can use signal handling mechanism. Register your method that will handle interrupt signals and just ignore it that in your function.
// signal handler
void my_function(int sig){
//do nothing
}
// register signal
signal(SIGNAL_ID, my_function);

Command clear won't take kill signal ( in infinite loop | c program )

I used the command "clear" in C language at infinite loop just for test and the kill signal does not stop it.
Why the program does not stop when i press Ctrl + C ?
#include <stdlib.h>
int main () {
while (1) {
system("clear");
}
return 0;
}
Killing clear will not help, because the infinite loop is in your own program. Kill that.
ControlC is only useful if you can get the system to pay attention. It sounds as if your terminal is too busy writing to the screen to do this.
From another terminal, run top and kill your program (which likely is near the top of the screen).
You could include a signal handler to 'catch' your CRTL-C input (which is SIGINT below) and then exit. Hopefully, this stub code will give you the idea. If not, I can provide a complete working example but would like to see you try first. :-)
#include <signal.h>
...
void stop (int signal) {
exit;
}
int main() {
signal(SIGINT, stop);
...
}
HTH

Signal Handling Functionalities in Ubuntu 11.04

I have tried to write a signal handling functions in ubuntu. The code is the following:
#include<signal.h>
void abc();
main(){
printf("Press Ctrl-z key to send SIGINT signal");
signal(SIGINT,abc);
for(;;);
}
void abc(){
printf("The key has been pressed");
}
The intersting factor is:
a) First printf() is not shown
b) As well as the second printf();
I wrote the code from a book. Can any one pls tell me what mistakes i have made or whether the code will be alterd for ubuntu.
Thanx in advance.
stdout is line buffered.
You might like to append a \n to the strings passed to printf():
printf("The key has been pressed.\n");
If Crtl-C is pressed SIGINT is sent to the process running in foreground. The default handler for SIGINT ends the app.
As the OP's app installs a signal handler for SIGINT which does not end the app, it continues to run if Ctrl-C is pressed and therefore a SIGINT is raised. It is called on Ctl-C as long as it stays installed.
To achieve the behaviour of having abc() called only once, modify the signal handler as follows:
void abc(int sig) /* 'sig' gets the signal nuber passed in (here: 'SIGINT') */
{
printf("The key has been pressed.\n");
signal(sig, SIG_DFT); /* (re-)sets the signal handler for `sig` to the default handler. */
}
Further readings: man signal, man sigaction

Why no output on console on signal handling?

I was trying this program from Advance Programming in Unix Environment.
#include<stdio.h>
#include<signal.h>
static void handler(int sig){
if(sig == SIGUSR1)
printf("handled user1 signal");
else if(sig == SIGUSR2)
printf("handles user2 signal");
else
printf("unkown signal");
}
int main(){
if(signal(SIGUSR1, handler) == SIG_ERR)
printf("can't handle signal SIGUSR1");
if(signal(SIGUSR2, handler) == SIG_ERR)
printf("can't handle signal SIGUSR2");
for(;;)
pause();
return 0;
}
I am using Ubuntu 11.10. I compile the program with gcc and then run a.out as indicated in the book.
$./a.out&
[1]+ 1345
$ kill -USR1 1345
But there is no output printed. The program keeps running in backgound and I have to kill it.
Other things I have tried:
Tried handling SIGINT to see if running program in background is causing problems. Still no output.
Downloaded latest release of FreeBSD and tried the same program on it, but with same problem.
I put a printf statement before setting signal handler:
int main(){
printf("printf is working...");
//exit(0);
if(signal(SIGUSR1, handler) == SIG_ERR)
...
when exit() is commented, there is no output. When I uncomment it, the output is printed.
Please tell me what am I doing wrong in this?
PS: Don't suggest using sigaction(). I am learning Unix Programming, not building any practical application.
The output from printf is buffered. That means it's stored in memory until flushed to the output. The best way to flush text in printf is to end the text with a newline. You can also flush manually with the fflush function.
However, you should be cautioned that using output functions like printf and fflush is not considered safe in signal handlers.

Resources