dotfiles/.config/i3blocks/weather/weather_signaler.c
2021-11-13 19:24:20 +01:00

103 lines
2.4 KiB
C

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <stdio.h>
// Sleep time between daemon updates.
#define SLEEP_TIME_S 300
// Test for internet connection. Returns true if connection is established.
static int test_internet_connection()
{
const char *cmd = "nc -zw1 google.com 443 1> /dev/null 2>&1";
return !system(cmd);
}
// Signal handler for signaling the weather applet.
static void timer_handler(int sig, siginfo_t *si, void *uc)
{
(void) sig; // Ignore parameter.
(void) si; // Ignore parameter.
(void) uc; // Ignore parameter.
// Test for internet connection till found or 20 times.
for (int i = 0; i < 20; ++i)
{
if (test_internet_connection())
{
// Connection established. Break out.
break;
}
else
{
// Retry every second.
sleep(1);
}
}
// Signal the weather applet.
const char *cmd = "pkill -RTMIN+2 i3blocks";
if ( system(cmd) )
{
// Error message should be printed to stdout since stdout is the way to
// interface with a user in i3blocks.
puts("WEATHER_SIGNALER ERROR\n");
}
}
int timer_init_launch(
timer_t *timer,
struct sigevent *sev,
struct sigaction *sa,
struct itimerspec *tspec)
{
// Event initialization.
sev->sigev_notify = SIGEV_SIGNAL;
sev->sigev_signo = SIGRTMIN;
sev->sigev_value.sival_ptr = timer;
// Signal action type initializaion.
sa->sa_flags = SA_SIGINFO;
sa->sa_sigaction = timer_handler;
sigemptyset(&sa->sa_mask);
if (sigaction(SIGRTMIN, sa, NULL) == -1)
return -1;
// Initialze timer.
if (timer_create(CLOCK_BOOTTIME, sev, timer) == -1)
return -1;
// Start the timer.
tspec->it_value.tv_sec = SLEEP_TIME_S;
tspec->it_value.tv_nsec = 0;
tspec->it_interval.tv_sec = SLEEP_TIME_S;
tspec->it_interval.tv_nsec = 0;
if (timer_settime(*timer, 0, tspec, NULL) == -1)
return -1;
// Initialization successful.
return 0;
}
int main()
{
timer_t timer;
struct sigevent sev;
struct sigaction sa;
struct itimerspec tspec;
// Initialize signaler
if (timer_init_launch(&timer, &sev, &sa, &tspec))
exit(EXIT_FAILURE);
// Signal on daemon launch.
sleep(1);
timer_handler(0, NULL, NULL);
while(1)
{
sleep(100);
}
}