Merge branch 'hooks-dir'

This commit is contained in:
Jon Lund Steffensen
2014-12-28 19:26:29 -05:00
6 changed files with 190 additions and 8 deletions
+19
View File
@@ -148,6 +148,25 @@ location\-provider=manual
lat=55.7
lon=12.6
.fi
.SH HOOKS
Executable files (e.g. scripts) placed in `~/.config/redshift/hooks'
will be run when a certain event happens. The first parameter to the
script indicates the event and further parameters may indicate
more details about the event. The event `period-changed' is indicated
when the period changes (`night', `daytime', `transition'). The second
parameter is the old period and the third is the new period. The event
is also signaled when Redshift starts up with the old period set to
`none'.
A simple script to handle these events can be written like this:
.IP
.nf
#!/bin/sh
case \fB$1\fR in
\fBperiod-changed\fR)
exec notify-send "Redshift" "Period changed to \fB$3\fR"
esac
.fi
.SH AUTHOR
.B redshift
was written by Jon Lund Steffensen <jonlst@gmail.com>.
+1
View File
@@ -15,6 +15,7 @@ redshift_SOURCES = \
location-manual.c location-manual.h \
solar.c solar.h \
systemtime.c systemtime.h \
hooks.c hooks.h \
gamma-dummy.c gamma-dummy.h
EXTRA_redshift_SOURCES = \
+113
View File
@@ -0,0 +1,113 @@
/* hooks.c -- Hooks triggered by events
This file is part of Redshift.
Redshift is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Redshift is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
Copyright (c) 2014 Jon Lund Steffensen <jonlst@gmail.com>
*/
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#ifndef _WIN32
# include <pwd.h>
#endif
#include "hooks.h"
#include "redshift.h"
#define MAX_HOOK_PATH 4096
/* Names of periods supplied to scripts. */
static const char *period_names[] = {
"none",
"daytime",
"night",
"transition"
};
/* Try to open the directory containing hooks. HP is a string
of MAX_HOOK_PATH length that will be filled with the path
of the returned directory. */
static DIR *
open_hooks_dir(char *hp)
{
char *env;
if ((env = getenv("XDG_CONFIG_HOME")) != NULL &&
env[0] != '\0') {
snprintf(hp, MAX_HOOK_PATH, "%s/redshift/hooks", env);
return opendir(hp);
}
if ((env = getenv("HOME")) != NULL &&
env[0] != '\0') {
snprintf(hp, MAX_HOOK_PATH, "%s/.config/redshift/hooks", env);
return opendir(hp);
}
#ifndef _WIN32
struct passwd *pwd = getpwuid(getuid());
snprintf(hp, MAX_HOOK_PATH, "%s/.config/redshift/hooks", pwd->pw_dir);
return opendir(hp);
#else
return NULL;
#endif
}
/* Run hooks with a signal that the period changed. */
void
hooks_signal_period_change(period_t prev_period, period_t period)
{
char hooksdir_path[MAX_HOOK_PATH];
DIR *hooks_dir = open_hooks_dir(hooksdir_path);
if (hooks_dir == NULL) return;
struct dirent* ent;
while ((ent = readdir(hooks_dir)) != NULL) {
/* Skip hidden and special files (., ..) */
if (ent->d_name[0] == '\0' || ent->d_name[0] == '.') continue;
char *hook_name = ent->d_name;
char hook_path[MAX_HOOK_PATH];
snprintf(hook_path, sizeof(hook_path), "%s/%s",
hooksdir_path, hook_name);
#ifndef _WIN32
/* Fork and exec the hook. We close stdout
so the hook cannot interfere with the normal
output. */
pid_t pid = fork();
if (pid == (pid_t)-1) {
perror("fork");
continue;
} else if (pid == 0) { /* Child */
close(STDOUT_FILENO);
int r = execl(hook_path, hook_name,
"period-changed",
period_names[prev_period],
period_names[period], NULL);
if (r < 0 && errno != EACCES) perror("execl");
/* Only reached on error */
_exit(EXIT_FAILURE);
}
#endif
}
}
+29
View File
@@ -0,0 +1,29 @@
/* hooks.h -- Hooks triggered by events
This file is part of Redshift.
Redshift is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Redshift is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Redshift. If not, see <http://www.gnu.org/licenses/>.
Copyright (c) 2014 Jon Lund Steffensen <jonlst@gmail.com>
*/
#ifndef REDSHIFT_HOOKS_H
#define REDSHIFT_HOOKS_H
#include "redshift.h"
void hooks_signal_period_change(period_t prev_period,
period_t period);
#endif /* ! REDSHIFT_HOOKS_H */
+19 -8
View File
@@ -47,6 +47,7 @@
#include "config-ini.h"
#include "solar.h"
#include "systemtime.h"
#include "hooks.h"
#define MIN(x,y) ((x) < (y) ? (x) : (y))
@@ -296,14 +297,6 @@ typedef enum {
PROGRAM_MODE_MANUAL
} program_mode_t;
/* Periods of day. */
typedef enum {
PERIOD_NONE = 0,
PERIOD_DAYTIME,
PERIOD_NIGHT,
PERIOD_TRANSITION
} period_t;
/* Names of periods of day */
static const char *period_names[] = {
/* TRANSLATORS: Name printed when period of day is unknown */
@@ -1445,6 +1438,18 @@ main(int argc, char *argv[])
perror("sigaction");
exit(EXIT_FAILURE);
}
/* Ignore CHLD signal. This causes child processes
(hooks) to be reaped automatically. */
sigact.sa_handler = SIG_IGN;
sigact.sa_mask = sigset;
sigact.sa_flags = 0;
r = sigaction(SIGCHLD, &sigact, NULL);
if (r < 0) {
perror("sigaction");
exit(EXIT_FAILURE);
}
#endif /* HAVE_SIGNAL_H && ! __WIN32__ */
if (verbose) {
@@ -1540,6 +1545,12 @@ main(int argc, char *argv[])
print_period(period, transition);
}
/* Activate hooks if period changed */
if (period != prev_period) {
hooks_signal_period_change(prev_period,
period);
}
/* Ongoing short transition */
if (short_trans_delta) {
/* Calculate alpha */
+9
View File
@@ -24,6 +24,15 @@
#include <stdlib.h>
/* Periods of day. */
typedef enum {
PERIOD_NONE = 0,
PERIOD_DAYTIME,
PERIOD_NIGHT,
PERIOD_TRANSITION
} period_t;
/* Color setting */
typedef struct {
int temperature;