Added shutdown daemon

This commit is contained in:
2018-11-22 03:04:40 +00:00
parent bb17008b55
commit f8ee591174
5 changed files with 192 additions and 8 deletions

1
.gitignore vendored
View File

@@ -218,3 +218,4 @@ dmypy.json
# Project target # Project target
robotd robotd
shutdownd

View File

@@ -1,15 +1,32 @@
TARGET = robotd TARGET = robotd shutdownd
OBJECT = robotd.o OBJECT = robotd.o shutdownd.o
SOURCE = robotd.c CFLAGS = -std=c11 -Wall -g -O0 -D _GNU_SOURCE
CFLAGS = -std=c11 -Wall -g -O0 `pkg-config --cflags python` LDLIBS = -lmraa
LDLIBS = -lmraa `pkg-config --libs python`
.PHONY: all .PHONY: all
all: $(TARGET) all: robotd shutdownd
$(TARGET): $(OBJECT) robotd: LDLIBS += `pkg-config --libs python`
robotd: robotd.o
$(OBJECT): $(SOURCE) robotd.o: CFLAGS += `pkg-config --cflags python`
robotd.o: robotd.c
shutdownd: shutdownd.o
shutdownd.o: shutdownd.c
install: robotd shutdownd init.sh shtdd.sh robot.service shutdown.service
cp robotd /usr/bin/robotd
cp shutdownd /usr/bin/shtdd
cp init.sh /etc/init.d/robot
cp shtdd.sh /etc/init.d/shtd
cp robot.service /lib/systemd/system
cp shutdown.service /lib/systemd/system
chmod a+x /etc/init.d/robot
chmod a+x /etc/init.d/shtd
systemctl enable robot.service
systemctl enable shutdown.service
.PHONY: clean .PHONY: clean
clean: clean:

57
shtdd.sh Executable file
View File

@@ -0,0 +1,57 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: shtd
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Shutdown daemon.
### END INIT INFO
start() {
if pidof shtdd > /dev/null
then
echo "shtdd already started."
return
else
echo "Starting shtdd"
shtdd
echo "Done."
fi
}
stop() {
if pidof shtdd > /dev/null
then
echo "Stopping shtdd"
kill -s INT `pidof shtdd`
echo "Done."
else
echo "shtdd already stopped."
fi
}
case "$1" in
start|restart|force-reload)
start
;;
stop)
stop
;;
status)
if pidof shtdd > /dev/null
then
echo "shtdd is running."
else
echo "shtdd is down."
fi
;;
restart)
stop
start
;;
*)
echo "Usage: {start|stop|restart|force-reload|status}"
exit 1
;;
esac

12
shutdown.service Normal file
View File

@@ -0,0 +1,12 @@
#! /bin/sh
[Unit]
Description=Shutdown daemon
[Service]
Type=forking
PIDFile=/var/run/shutdown.pid
WorkingDirectory=/home/root/Robotd
ExecStart=/etc/init.d/shtd start
ExecReload=/etc/init.d/shtd restart
ExecStop=/etc/init.d/shtd stop
[Install]
WantedBy=multi-user.target

97
shutdownd.c Normal file
View File

@@ -0,0 +1,97 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <stdbool.h>
#include <mraa.h>
#define GPIO_PIN_12 12
#define MRAA_CHECK_RESULT(X, Y, Z, Q) \
if (X == MRAA_SUCCESS) { \
syslog(LOG_DAEMON | LOG_NOTICE, Y); \
} else { \
syslog(LOG_DAEMON | LOG_ERR, Z); \
if (Q) { \
clean_up(); \
exit(EXIT_FAILURE); \
} \
}
void clean_up() {
syslog(LOG_DAEMON | LOG_WARNING, "Cleaning up.");
closelog();
}
void sig_handler(int signal) {
syslog(LOG_DAEMON | LOG_WARNING, "Shutdown daemon interrupted.");
clean_up();
exit(EXIT_FAILURE);
}
int main(int argc, char ** argv) {
int rv;
bool done = false;
sighandler_t sh;
mraa_result_t mr;
mraa_gpio_context pin12;
// Turn the process into a daemon.
rv = daemon(0, 1);
if (rv != 0) {
perror("daemon(0, 1)");
return EXIT_FAILURE;
}
// Set SIGINT signal handler
sh = signal(SIGINT, sig_handler);
if (sh == SIG_ERR) {
perror("sh = signal(SIGINT, sig_handler)");
return EXIT_FAILURE;
}
// Create PID file
FILE * pid = fopen("/var/run/shutdown.pid", "w");
if (pid == NULL) {
perror("FILE * pid = fopen(\"/var/run/shutdown.pid\", \"w\")");
syslog(LOG_DAEMON | LOG_ERR, "Failed to create PID file.");
return EXIT_FAILURE;
}
fprintf(pid, "%d", getpid());
fclose(pid);
// Open a syslog connection
openlog(argv[0], LOG_NDELAY | LOG_PID, LOG_DAEMON);
syslog(LOG_DAEMON | LOG_NOTICE, "Started shutdown daemon.");
// Open PIN 12 as a PULLUP input pin for the push button
pin12 = mraa_gpio_init(GPIO_PIN_12);
mr = mraa_gpio_dir(pin12, MRAA_GPIO_IN);
MRAA_CHECK_RESULT(mr, "Opened push button pin.", "Failed to open push button pin.", true);
mr = mraa_gpio_mode(pin12, MRAA_GPIO_PULLUP);
MRAA_CHECK_RESULT(mr, "Push button ready.", "Failed to set push button mode.", true);
// Start pin processing loop
while (!done) {
rv = mraa_gpio_read(pin12);
if (rv == 0) {
// If the button is pressed then stop reading and go on with the program
syslog(LOG_DAEMON | LOG_NOTICE, "Button push detected.");
done = true;
}
}
syslog(LOG_DAEMON | LOG_NOTICE, "Finishing.");
closelog();
execlp("shutdown", "shutdown", "-Ph", "now", (char *)NULL);
return EXIT_SUCCESS;
}