matkuz
matkuz

Reputation: 27

Clock_nanosleep in linux

I have some difficult with clock_nanosleep but step by step:

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

Answers (1)

alk
alk

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

Related Questions