Basic signal and alarm usage

I am trying to write a program that will;
1) Show the message "Snoozing now...zzzz" on the screen for 5 seconds
2) Then in the same position show the message "The ALARM is going off now!" for 5 seconds
3) Repeat 1) then 2) infinitely until user presses Ctrl C

I can't make it work. Any hints appreciated.
Here is my code;

[me@myplace]$ cat main10.c
/* main10.c
testing signals and alarms */

#include <curses.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

void handler( void )
{
clear();
mvprintw(10, 10, "The ALARM is going off now!\n" );
refresh();
signal( SIGALRM, handler );
alarm( SIGALRM, 5 );
}

int main( void )
{
clear();
signal( SIGALRM, handler );
alarm( SIGALRM, 5 );
mvprintw( 10, 10, "Snoozing now..zzzzzz\n");
refresh();
endwin();
}
[me@myplace]$ gcc main10.c -lcurses -o mainApp10
main10.c: In function `handler':
main10.c:17: warning: passing arg 2 of `signal' from incompatible pointer type
main10.c: In function `main':
main10.c:24: warning: passing arg 2 of `signal' from incompatible pointer type
[me@myplace]$ mainApp10
Segmentation fault
[me@myplace]$

Where is the curses mode initialized,

initscr();

Modified your code,

alarm prototype is not correct!

Check this,

#include <curses.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

void handler(void);

void handler( void )
{
clear();
mvprintw(10, 10, "The ALARM is going off now!\n" );
refresh();
signal( SIGALRM, handler );
alarm( 5 );
}

int main( void )
{
initscr();
clear();
signal( SIGALRM, handler );
alarm( 5 );
mvprintw( 10, 10, "Snoozing now..zzzzzz\n");
getch();
refresh();
endwin();
return 0;
}

Thanks a lot. matrixmadhan your code almost works perfectly. The only thing it doesn't do is loop infinitely between "The ALARM...." and "Snoozing.....".

It starts by displaying "Snoozing....." than after 5 seconds "The ALARM....". This is good. But then "The ALARM...." stays on screen forever. I want it to then revert back to "Snoozing....." and then back to "The ALARM...." etc etc etc in an infinite loop every 5 seconds.

I will try to modify. Any more hints appreciated.

Although that may be a jolly program, that is far too much code for a signal handler.

C libraries are not "signal safe", the most you should be doing in a signal handler is setting a flag or a minimal bit of IPC to awaken the main program.

If your handler was called in the middle of malloc your heap could get trashed.

One way:

#include <curses.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

void handler(int sig) { }

int main( void )
{
        int state;
        signal(SIGALRM, handler);
        initscr();
        clear();
        state=0;
        while(1) {
                if(state) {
                        mvprintw(10, 10, "The ALARM is going off now!\n" );
                } else {
                        mvprintw( 10, 10, "Snoozing now..zzzzzz\n");
                }
                refresh();
                alarm(5);
                pause();
                state=!state;
        }
}

Thanks very much to all. I have a project in mind and this forms a piece of it. I will forge ahead now. You have helped me understand how to implement alarms and signals.

Your signal handler has the ideal amount of code!

Now time to start looking at how to block and unblock the signals so they only occur during the pause().

Eg, what happens if you are on a really slow or heavily loaded box and the following sequence occurs...

alarm(5)

<----- signal fires here ----->

pause()

Then pause() would never see the signal and would hang.

OK thanks, I will look into this issue.

porter's objection is a bit frivolous... if we cannot execute two successive system calls during a 5 second period, we do not have the resources available to run a program that that displays alternating messages every 5 seconds. But I will fix that objection anyway since I see a more serious problem. The signal() function may set the SA_RESETHAND flag on some versions of Unix. So to be portable, I would need to move that signal call into the loop and set it every time. Instead of that I would prefer to to switch to sigaction() so I can portably install the handler one time. Once I do that, I may as well, switch pause() to sigsuspend() to fix porter's objection. So...

#include <curses.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

void handler(int sig) { }

int main( void )
{
        int state;
        sigset_t imask, omask;
        struct sigaction act, oact;
        sigemptyset(&imask);
        sigemptyset(&omask);
        sigaddset(&imask, SIGALRM);

        sigemptyset(&act.sa_mask);
        act.sa_handler = handler;
        act.sa_flags = 0;
        sigaction(SIGALRM, &act, &oact);

        initscr();
        clear();
        state=0;
        while(1) {
                if(state) {
                        mvprintw(10, 10, "The ALARM is going off now!\n" );
                } else {
                        mvprintw( 10, 10, "Snoozing now..zzzzzz\n");
                }
                refresh();
                sigprocmask(SIG_SETMASK, &imask, NULL);
                alarm(5);
                sigsuspend(&omask);
                state=!state;
        }
}

Also, I want to point out that in real life I would call sleep() to get a 5 second delay. I assume that, for purposes of this thread, that would be cheating.

Thanks again. I will sift through your code. There is much for me to learn in there.

Could you please explain the purpose of the following statement;

Why does the program contain no prototype of this function?
Further, I do not understand what it does or how. Thanks.

prototypes are a good idea but are never required in c. Even in c++ a prototype would not be required because the entire function appears in the source file before it is used. The function does nothing at all... an empty function is legal and it behaves like it just had a a single return statement in it. But we need some function to install if the program is going to respond to signals. Without a function our choices are to ignore signals or die upon their receipt.

Not true, they *are* required if the function has not already been seen and returns anything other than an int. This is true even in K&R C.

Two examples why....

  1. if the function returns a double some architectures require an FPU pop even if the value is not used.

  2. if the function returns a struct it requires a certain amount of extra stackspace to be allocated in addition to an extra hidden pointer.

Finally,

If using GNU C use the options -Wall and -Werror, they actually help.

Yes.

#include <stdio.h>

//char* fun(int);

int main()
{
  fun(10);
  return 0;
}

char* fun(int a) {
  return "";
}

Upon compilation,
implicit declaration of ' int ' would be considered for the function fun ' fun ' while the definition is returning ' char* '

IMHO, signatures are a must.

No, that is not true. Function definitions are what would be required in the cases you cite. Function prototypes did not arrive until Ansi C. You have the two mixed up.

function definition: int handler();
function prototype: int handler(int);

The original C language did not support prototypes and, while they are a good idea, they are not required now.

so what will the following do?

main()
{
long l=get_number();

      printf("%ld\n",l);

      return 0;
}

double get_number()
{
     return 3.141592654;
}

I guess it demonstrates that you are able to generate an incorrect program that doesn't use function prototypes. This suggests that you think this is proof that function prototypes are required and possibly even that the original K&R C supported or required function prototypes. It must at least be true that you think the addition of a function prototype is the only way to fix the program. (I remain convinced that a function definition would fix it as well.) Oh well, at least you finally contributed some code to this thread.

A quote for anyone who is interested...

From The C Programming Language Second Edition by Brian Kernighan and Dennis Ritchie

porter, you and I will simply have to agree to disagree on whether or not function prototypes are currently required as well as whether or not function prototypes were supported (or required) by the original K&R C. I am closing this thread.