Reputation: 27
I have some difficult with clock_nanosleep but step by step:
my program react to SIGUSR1 sygnal
my program should do endless loop until get SIGALRM fro clock_nanosleep.
But it doesn't work - after send SIGUSR1 program all the time do endless loop! Anybody help ?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
int fd;
void czekaj_czas()
{
struct sigevent evp;
struct itimerspec ts2;
timer_t timer;
int ret2 ;
evp.sigev_value.sival_ptr = &timer;
evp.sigev_notify = SIGEV_SIGNAL;
evp.sigev_signo = SIGALRM;
ret2 = timer_create(CLOCK_MONOTONIC,&evp,&timer);
if(ret2)
perror("Blad funkcji timer_create");
ts2.it_interval.tv_sec = 3;
ts2.it_interval.tv_nsec = 0;
ts2.it_value.tv_sec = 3;
ts2.it_value.tv_nsec = 0;
if(timer_settime(timer,0,&ts2,NULL))
perror("timer_settime");
}
void handler_signal(int signal)
{
sigset_t pending; // syngaly oczekujace
int losowy_czas ;
struct timespec ts;
int ret;
char buf[10];
int ret3;
ssize_t ret_out;
int wyjsc = 1;
int j = 0;
srand((unsigned int) time(NULL));
losowy_czas = rand() % 15 + 5;
ts.tv_sec = 0;
ts.tv_nsec = losowy_czas * 100000000;
ret = clock_nanosleep(CLOCK_MONOTONIC,0,&ts,NULL);
switch(signal)
{
case SIGUSR1:
czekaj_czas();
break;
case SIGALRM:
wyjsc = 0;
break;
default:
fprintf(stderr,"Zlapany zly sygnal: %d \n", signal);
return;
}
if(ret)
perror("Funkcja zakonczona, signal dostarczony do procesu");
fd = open("file.txt", O_RDWR | O_CREAT | O_APPEND);
snprintf(buf, 10, "cos cos");
while(wyjsc)
{
ret_out = write(fd, buf, strlen(buf));
if(ret_out == -1)
perror("blad zapisu do bliku");
}
}
int main(int argc, char *argv[])
{
int i;
long val;
char *endptr;
struct sigaction sa;
int fd;
sa.sa_handler = &handler_signal;
sa.sa_flags = SA_RESTART | SA_NODEFER ;
//blokowanie wszystkich innych sygnalow
sigfillset(&sa.sa_mask);
if(sigaction(SIGUSR1,&sa,NULL) == -1)
{
perror("Nie mozna obsluzyc SIGUSR1");
}
if(sigaction(SIGALRM,&sa,NULL) == -1)
{
perror("Nie mozna obsluzyc SIGALRM");
}
for(i=0; i<2000; i++)
{
printf("Running %i \n", i);
sleep(1);
}
return;
}
Upvotes: 0
Views: 641
Reputation: 70951
The signal handler called call for SIGALRM
does not use the same stack as the signal handler called for SIGUSR1
. Due to this the wyjsc
(living on the stack created for the call) for SIGUSR1
is not (re-)set when SIGALRM
gets handled.
To fix this make wyjsc
global like for example so:
sig_atomic_t wyjsc = 0;
Upvotes: 1