c check signals every n seconds

python signal
pcntl_signal
sigterm
pcntl_signal_dispatch
python signal sigterm
sigusr1
sighup
ctrl-c signal

I'm tyring to write a program that every 5 seconds checks all the signals received and varies its output depending on them. My main issue is making the code actually wait the 5 seconds, since the function sleep() gets interrupted as soon as a signal is processed. What I have tried to do is fork the program into two processes, and have only the child work with the signals, and communicate them by a pipe. The issue is that, being the pipe blocking, after the first 5 second, the parent will just try to read there, basically making the sleep useless.

In theory I should be able to solve such problem just using the libraries I included (or in alternative with pthread library,it's an assignment), otherwise I saw I could use other libraries to make the pipe not blocking, but at the moment I'm short of ideas on how to fix this (I also tried a failed attempt with thread).

I attach the code for reference, thanks in advance.

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int p[2];//pipe

void sigHandler (int sig) {
    char c;
    switch (sig) {
        case SIGUSR1:
            c = '1';
        break;
        case SIGUSR2:
            c = '2';
        break;
        case SIGALRM:
            c = '0';
        break;
        case SIGSTOP:
            exit (0);
        break;
    }
    write(p[1], &c, sizeof(char));
}


int main(int argc, char **argv) {
    int signals[3], sig, i;
    for (i=0; i< 3; i++) {
        signals[i] =0;
    }
    pid_t pid;
    char csig;
    pipe(p);

    /*fork code*/
    pid = fork();

    /*parent*/
    if (pid) { 
        close(p[1]);
        int proceed = 1;

        /*cycle keeps on indefinitely*/
        while (proceed) {
            sleep(15); //increased the time so I have time to send signals
            while (read(p[0], &csig, sizeof(char)) > 0) {
                sig=atoi(&csig);
                signals[sig]++;

                /*if alternating sigals, error*/
                if (signals[1] && signals[2]) {
                    printf("Error: alternating SIGUSR1 and SIGUSR2\n%d\t%d\n", signals[1], signals[2]);

                }
                /*if 2 consecutive signals, success*/
                if (signals[sig] == 2) {
                    printf("Success: two consecutive SIGUSR1 or SIGUSR2\n");
                }
                /*if three consecutive signals, exit*/
                if (signals[sig] == 3) {
                    kill(pid, SIGSTOP);
                    proceed = 0;
                    break;
                }
                /*make 0 any non repeating signal != sig*/
                for(i = 0; i< 3; i++) {
                    if (i != sig) {
                        signals[i] = 0;
                    }
                }
            }
        }
    /*child*/
    } else {
        close(p[0]);
        signal(SIGUSR1, sigHandler);
        signal(SIGUSR2, sigHandler);
        signal(SIGALRM, sigHandler);
        signal(SIGSTOP, sigHandler);
        while (1) {
            sleep(5); //no need to do anything else
        }
        exit(1);

    }
    return 0;
}
  1. Compute what time it will be in five seconds. Store this time.
  2. Compute how long it will be until the time you computed in step 1.
  3. Sleep for that long.
  4. Check the time.
  5. If it's at or past the time you stored in step 1, you are done.
  6. Go to step 2.

c check signals every n seconds, c check signals every n seconds. sigchld c signal python wait() python sleep milliseconds python delay without sleep sigchld in c c timer thread example The C library function void (*signal(int sig, void (*func)(int)))(int) sets a function to handle signal i.e. a signal handler with signal number sig. (Signal Floating-Point Exception) Erroneous arithmetic operation, such as zero divide or an operation resulting in overflow (not necessarily with a

clock_nanosleep lets you sleep till an absolute time. You can repeatedly call this function till the desired time is reached.

struct timespec time_now;
clock_gettime(CLOCK_REALTIME, &time_now);
time_now.tv_sec += 5;
time_now.tv_nsec = 0;
while(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &time_now, NULL) == EINTR);

This will make your thread to sleep repeatedly till it has completed a sleep of 5 seconds. In your signal handler, you keep adding the received signals to an array and handle it after the sleep is over.

Instruction Manual for Obtaining Oceanographic Data, This will cause the red reload indicator signal (A) to light (fig. C-20). NOTE: Included with each XBT system is a Model A2-A test canister. Its circuit is 4,700​n± O.I % WW 21,987/1+0.1 % Figure C-21. Test C-20) for 30 or 40 seconds. For reference, here is a list of all the signals on Linux. The signals from SIGRTMIN and above are real time signals. $ uname -a: Linux localhost 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 GNU/Linux

Why so complicated? Signals are a per-process (and optionally per-thread within same the process when POSIX threads are used), so it makes no sense to use multiple processes just to handle signals.

Consider the following program:

#define  _POSIX_C_SOURCE  200809L
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

static const char *signal_name(const int signum)
{
    switch (signum) {
    case SIGUSR1: return "SIGUSR1";
    case SIGUSR2: return "SIGUSR2";
    case SIGALRM: return "SIGALRM";
    case SIGSTOP: return "SIGSTOP";
    case SIGINT:  return "SIGINT";
    default:      return "unnamed";
    }
}

int main(void)
{
    siginfo_t  info;
    sigset_t   mask;
    int        signum;

    sigemptyset(&mask);
    sigaddset(&mask, SIGUSR1);
    sigaddset(&mask, SIGUSR2);
    sigaddset(&mask, SIGALRM);
    sigaddset(&mask, SIGSTOP);
    sigaddset(&mask, SIGINT);

    /* Block the signals in mask. */
    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
        fprintf(stderr, "Cannot block signals: %s.\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    printf("Process %d is ready for USR1 and USR2 signals.\n", (int)getpid());
    fflush(stdout);

    /* Ensure we receive a SIGALRM signal in five seconds or so. */
    alarm(5);

    while (1) {

        /* Receive one of the signals in mask. */ 
        signum = sigwaitinfo(&mask, &info);
        if (signum == -1) {
            const int  err = errno;

            /* EINTR should not happen, but if it did, it would be okay. */
            if (err == EINTR)
                continue;

            fprintf(stderr, "sigwaitinfo() failed: %s (%d).\n", strerror(err), err);
            exit(EXIT_FAILURE);
        }

        /* Describe the received signal. */
        if (info.si_pid)
            printf("Received %s (signal %d) from process %d.\n", signal_name(signum), signum, (int)info.si_pid);
        else
            printf("Received %s (signal %d).\n", signal_name(signum), signum);
        fflush(stdout);

        /* It is time to exit, if we receive INT or STOP, */
        if (signum == SIGINT || signum == SIGSTOP)
            break;

        /* or an ALRM timeout; don't be fooled by kill()/sigqueue() SIGALRM. */
        if (signum == SIGALRM && !info.si_pid)
            break;
    }

    printf("Done.\n");
    return EXIT_SUCCESS;
}

mask contains the set of signals blocked and only received via sigwaitinfo(). alarm(5) ensures a SIGALRM signal is delivered in five seconds or so. If info.si_pid is set, the signal was sent via kill() (or similar OS-specific syscalls).

This program just describes each signal it receives, until the alarm timeout triggers, or it receives a SIGSTOP or SIGINT signal. (When you run the program in a terminal, and press Ctrl+C, the terminal sends a SIGINT signal to the (foreground) process.)

You cannot fool the program by sending it a SIGALRM signal, because the kernel sets the .si_pid field of the siginfo_t structure to the sending process; it will be zero for all "genuine" alarms.

Remember that standard Unix/POSIX signals are not queued, and may have latency (like sleeps and timers, may be delivered later than intended).

NASA technical note, 0 Internal ATMN A ( 21 ) Any ALP coded body name Input CLEAR C ( 3 ) Any value Input Input 10 - 6 DELMAX Any number of seconds A ( 19 ) A ( 5 ) Normally equal to 0 . 0 Internal If and when C ( LOOKX ) - XLOOK , SIGNAL 18 set to 1 . 18 set as time at which program will begin checking for return to orbit elements . By accessing this web site, you are agreeing to the Terms and Conditions in the Second Signal User Agreement.

Railway Signaling and Communications, 1919 . periods of 30 seconds each , allowing 10 seconds at . The lowest more than 10 or less than 2 cells for each test . Elsworth ( N . Y . C . ) stated that the original designa1920 . tion of a cell by the ampere hour capacity was not satis( 1 )  Persistent Signal Error: Uverse Signal has been lost I have rebooted the entire system several times; however, problem persists. Each channel will play fine for approximately 10 seconds and then freezes.

The Signal Engineer, 6 *(N-3) "MO" Signal No.26 *(O-B) “1'41" *Register mark indicating special 3, are checked by a special committee, and each failure is carefully dissected and Notez—Record is subdivided as follows: “C":—-Signals indicating proceed with territory; you can in a few seconds review the history of any signal, switch, etc. If you employ a good visual search while driving, you will: a. Check your rearview mirror every 5 seconds b. Know the year of the vehicle behind you

MC68HC12 an Introduction: Software and Hardware Interfacing, E8.2 Use input-capture channel 1 to measure the duty cycle of a signal. E8.5 Write an assembly and a C program to generate a 4 KHz, 80% duty cycle an interrupt every second and output the message “n seconds has passed. E8.11 In Example 8.3, we are using the polling method to check for the arrival of edges. Signals is your online catalog of uniquely thoughtful personalized gifts, clothing, jewelry, accessories, home décor, and more gifts for all ages and occasions!

Comments
  • Why do you need a separate child process? In the same process if you get a signal, just add it to a queue and resume the sleep for the remaining amount of time. You can easily check if your sleep was interrupted or it finished the time. Check the return value for sleep
  • Perhaps thread suspending and resuming?
  • Maybe call sigsetmask or sigprocmask before and after the sleep(5) if you only want signals to be processed every 5 seconds.
  • Sleep also returns the amount left if it was interrupted. Don't need to calculate again.
  • @AjayBrahmakshatriya But that's rounded to the nearest second which might not be accurate enough for a five second sleep. Even if you only use second accuracy with the algorithm above, at least errors from multiple interruptions won't accumulate. But if interruptions are rare and accuracy isn't particularly important, that's definitely an option.
  • @AjayBrahmakshatriya: it also does not include the time spent in the signal handler (or the time waking up the process to run the signal handler, or other overhead outside of sleep). So if a lot of signals are delivered you may end up waiting noticeably longer than the desired amount of time.,,
  • The time spent actually processing the signal that interrupted the nanosleep call is not included in (subtracted from) the time remaining returned, so if there are a lot of signals, this may be quite inaccurate.
  • @ChrisDodd I assumed that the overhead of that would be low because the signal handler would be short. Anyway, I changed the answer to use absolute time instead.