From f8ee5911740cb76fa37141383acb14e0900f210b Mon Sep 17 00:00:00 2001 From: Miguel Angel Astor Romero Date: Thu, 22 Nov 2018 03:04:40 +0000 Subject: [PATCH] Added shutdown daemon --- .gitignore | 1 + Makefile | 33 ++++++++++++---- shtdd.sh | 57 ++++++++++++++++++++++++++++ shutdown.service | 12 ++++++ shutdownd.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 192 insertions(+), 8 deletions(-) create mode 100755 shtdd.sh create mode 100644 shutdown.service create mode 100644 shutdownd.c diff --git a/.gitignore b/.gitignore index 38dc2db..fd54021 100644 --- a/.gitignore +++ b/.gitignore @@ -218,3 +218,4 @@ dmypy.json # Project target robotd +shutdownd diff --git a/Makefile b/Makefile index ef0d4d2..8b35f49 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,32 @@ -TARGET = robotd -OBJECT = robotd.o -SOURCE = robotd.c -CFLAGS = -std=c11 -Wall -g -O0 `pkg-config --cflags python` -LDLIBS = -lmraa `pkg-config --libs python` +TARGET = robotd shutdownd +OBJECT = robotd.o shutdownd.o +CFLAGS = -std=c11 -Wall -g -O0 -D _GNU_SOURCE +LDLIBS = -lmraa .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 clean: diff --git a/shtdd.sh b/shtdd.sh new file mode 100755 index 0000000..ba04e3f --- /dev/null +++ b/shtdd.sh @@ -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 diff --git a/shutdown.service b/shutdown.service new file mode 100644 index 0000000..e2800b4 --- /dev/null +++ b/shutdown.service @@ -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 diff --git a/shutdownd.c b/shutdownd.c new file mode 100644 index 0000000..d17ea4c --- /dev/null +++ b/shutdownd.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +}