From 4a9df9b604cec6ee4b4a6f01ef940443583f7573 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Thu, 26 Dec 2019 18:32:26 +0100 Subject: Still working on the daemonization (and rewrite). I am not sure that what I am doing is going to provide what was requested in https://github.com/nsensfel/relabsd/issues/3 but it will at the very least turn relabsd into a proper daemon, and the additions will help create some kind of relabsd device manager if someone needs such a thing. --- src/server/communication_node.c | 177 ++++++++++++++++++++++++++++++++++++++ src/server/communication_thread.c | 55 ++++++++++++ src/server/conversion_main_loop.c | 173 +++++++++++++++++++++++++++++++++++++ src/server/daemon.c | 113 ++++++++++++++++++++++-- src/server/main_loop.c | 165 ----------------------------------- src/server/server.c | 15 +++- 6 files changed, 521 insertions(+), 177 deletions(-) create mode 100644 src/server/communication_node.c create mode 100644 src/server/communication_thread.c create mode 100644 src/server/conversion_main_loop.c delete mode 100644 src/server/main_loop.c (limited to 'src/server') diff --git a/src/server/communication_node.c b/src/server/communication_node.c new file mode 100644 index 0000000..70c7323 --- /dev/null +++ b/src/server/communication_node.c @@ -0,0 +1,177 @@ +/**** POSIX *******************************************************************/ +#include +#include + +#include +#include +#include +#include + +/**** RELABSD *****************************************************************/ +#include + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ + +static int create_socket (int result [const restrict static 1]) +{ + errno = 0; + + *result = socket(AF_UNIX, SOCK_STREAM, 0); + + if (*result == -1) + { + RELABSD_FATAL + ( + "Unable to create server socket: %s.", + strerror(errno) + ); + + return -1; + } + + return 0; +} + +static int bind_socket +( + const char socket_name [const restrict static 1], + const int socket +) +{ + struct sockaddr_un addr; + + + memset(&addr, 0, sizeof(struct sockaddr_un)); + + addr.sun_family = AF_UNIX; + + strncpy + ( + (void *) addr.sun_path, + (const void *) socket_name, + (sizeof(addr.sun_path) - 1) + ); + + errno = 0; + + if + ( + bind + ( + socket, + (const struct sockaddr *) &addr, + (socklen_t) sizeof(struct sockaddr_un) + ) + == -1 + ) + { + RELABSD_FATAL + ( + "Unable to bind communication socket to %s: %s.", + socket_name, + strerror(errno) + ); + + return -1; + } + + return 0; +} + +static int set_socket_to_unblocking (const int socket) +{ + int current_flags; + + errno = 0; + current_flags = fcntl(socket, F_GETFD); + + if (current_flags == -1) + { + RELABSD_FATAL + ( + "Unable to get communication socket properties: %s.", + strerror(errno) + ); + + return -1; + } + + errno = 0; + current_flags = fcntl(socket, F_SETFD, (current_flags | O_NONBLOCK)); + + if (current_flags == -1) + { + RELABSD_FATAL + ( + "Unable to set communication socket properties: %s.", + strerror(errno) + ); + + return -2; + } + + return 0; +} + +static int set_socket_as_listener (const int socket) +{ + errno = 0; + + if (listen(socket, 0) == -1) + { + RELABSD_FATAL + ( + "Unable to set server socket properties: %s.", + strerror(errno) + ); + + return -1; + } + + return 0; +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_server_create_communication_node +( + const char socket_name [const restrict static 1], + int socket [const restrict static 1] +) +{ + if (create_socket(socket) < 0) + { + return -1; + } + + if (bind_socket(socket_name, *socket) < 0) + { + /* TODO: err message. */ + (void) close(*socket); + + return -1; + } + + /* + if (set_socket_to_unblocking(*socket) < 0) + { + /* TODO: err message. *//* + (void) close(*socket); + + return -1; + } + */ + + if (set_socket_as_listener(*socket) < 0) + { + /* TODO: err message. */ + (void) close(*socket); + + return -1; + } + + return 0; +} diff --git a/src/server/communication_thread.c b/src/server/communication_thread.c new file mode 100644 index 0000000..2ed1aae --- /dev/null +++ b/src/server/communication_thread.c @@ -0,0 +1,55 @@ +/**** POSIX *******************************************************************/ +#include +#include + +/**** RELABSD *****************************************************************/ +#include + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ +void main_loop (struct relabsd_server server [const static 1]) +{ + +} + +void * posix_main_loop (void * params) +{ + main_loop((struct relabsd_server *) params); + + return NULL; +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ + +int relabsd_server_create_communication_thread +( + struct relabsd_server server [const static 1] +) +{ + int err; + + err = + pthread_create + ( + &(server->communication_thread), + (const pthread_attr_t *) NULL, + posix_main_loop, + (void *) server + ); + + if (err != 0) + { + RELABSD_FATAL + ( + "Unable to create the communication thread: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} diff --git a/src/server/conversion_main_loop.c b/src/server/conversion_main_loop.c new file mode 100644 index 0000000..0180e80 --- /dev/null +++ b/src/server/conversion_main_loop.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include + +#include "pervasive.h" +#include "error.h" +#include "config.h" +#include "input.h" +#include "relabsd_device.h" + +static int RELABSD_RUN = 1; + +static void interrupt (int unused_mandatory_parameter) +{ + RELABSD_RUN = 0; + + RELABSD_S_WARNING("Interrupted, will exit at the next input device event."); +} + +static void handle_relative_axis_event +( + struct relabsd_config * const conf, + const struct relabsd_device * const dev, + unsigned int const input_type, + unsigned int const input_code, + int value +) +{ + unsigned int abs_code; + enum relabsd_axis rad_code; + + rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code); + + switch (relabsd_config_filter(conf, rad_code, &value)) + { + case -1: + /* 'conf' doesn't want the event to be transmitted. */ + break; + + case 0: + /* 'conf' wants the event to be transmitted as is. */ + relabsd_device_write_evdev_event(dev, input_type, input_code, value); + break; + + case 1: + /* 'conf' allows the value to be emitted */ + relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value); + break; + } +} + +static void convert_input +( + struct relabsd_config * const conf, + struct relabsd_input * const input, + const struct relabsd_device * const dev +) +{ + unsigned int input_type, input_code; + int value; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Handling input events..."); + + input->timed_out = 1; + + while (RELABSD_RUN == 1) + { + if (conf->enable_timeout) + { + switch (relabsd_input_wait_for_next_event(input, conf)) + { + case 1: + input->timed_out = 0; + break; + + case 0: + relabsd_device_set_axes_to_zero(dev, conf); + input->timed_out = 1; + break; + + case -1: + continue; + } + } + + if (relabsd_input_read(input, &input_type, &input_code, &value) < 0) + { + /* + * The next event should not be retransmitted, or some kind of error + * happened. + */ + /* TODO: error handling. */ + continue; + } + + if (input_type == EV_REL) + { + /* We might have to convert the event. */ + handle_relative_axis_event(conf, dev, input_type, input_code, value); + } + else + { + /* Any other event is retransmitted as is. */ + relabsd_device_write_evdev_event(dev, input_type, input_code, value); + } + } +} + +static int set_signal_handlers () +{ + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers."); + + if (signal(SIGINT, interrupt) == SIG_ERR) + { + RELABSD_S_FATAL("Unable to set the SIGINT signal handler."); + + return -1; + } + + return 0; +} + +/* +int main (int argc, char ** argv) +{ + struct relabsd_config conf; + struct relabsd_input input; + struct relabsd_device dev; + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd started."); + + if (set_signal_handlers() < 0) + { + return -1; + } + + if (relabsd_config_parse(&conf, argc, argv) < 0) + { + return -2; + } + + if (relabsd_input_open(&input, &conf) < 0) + { + return -3; + } + + if (relabsd_device_create(&dev, &conf) < 0) + { + return -4; + } + + convert_input(&conf, &input, &dev); + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Terminating..."); + + relabsd_device_destroy(&dev); + relabsd_input_close(&input); + + RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Done."); + + return 0; +} +*/ + +int relabsd_server_conversion_loop +( + struct relabsd_server server [const static 1] +) +{ + return 0; +} diff --git a/src/server/daemon.c b/src/server/daemon.c index 7b8e736..c8561f3 100644 --- a/src/server/daemon.c +++ b/src/server/daemon.c @@ -1,14 +1,13 @@ /**** POSIX *******************************************************************/ -#include +#include +#include +#include +#include #include /**** RELABSD *****************************************************************/ -#include #include -#include - -#include /******************************************************************************/ /**** LOCAL FUNCTIONS *********************************************************/ @@ -26,10 +25,24 @@ */ int relabsd_server_create_daemon (void) { + int unnamed_pipe[2]; pid_t proc_id; + errno = 0; + + if (pipe(unnamed_pipe) == -1) + { + RELABSD_FATAL + ( + "Unable to create an unnamed pipe for the daemon creation process: %s", + strerror(errno) + ); + + return -1; + } + /* 1/ Close all open file descriptors ... **********************************/ - /* None were opened at this point. */ + /* None were opened at this point, except the pipe, which is still needed. */ /* 2/ Reset all signal handlers ... ****************************************/ /* Those were not modified at this point. */ @@ -57,10 +70,52 @@ int relabsd_server_create_daemon (void) if (proc_id != ((pid_t) 0)) { + char buffer; + + /* Close the writing end of the pipe, as this process does not use it */ + errno = 0; + + if (close(unnamed_pipe[1]) == -1) + { + RELABSD_ERROR + ( + "Unable to close writing end of an unnamed pipe during the daemon" + " creation process: %s.", + strerror(errno) + ); + } + /* Awaiting step 14...*/ - /* TODO: insert unnamed pipe */ + errno = 0; + + if (read(unnamed_pipe[0], &buffer, (size_t) 1) == -1) + { + RELABSD_ERROR + ( + "Unable to read from reading end of an unnamed pipe during the " + " daemon creation process: %s.", + strerror(errno) + ); + } + + if (close(unnamed_pipe[0]) == -1) + { + RELABSD_ERROR + ( + "Unable to close reading end of an unnamed pipe during the daemon" + " creation process: %s.", + strerror(errno) + ); + } + /* 15/ Original process exits *******************************************/ - exit(); + exit(0); + } + + /* Close reading on the pipe, as this process does not use it */ + if (close(unnamed_pipe[0])) + { + } /* 6/ setsid() *************************************************************/ @@ -96,13 +151,26 @@ int relabsd_server_create_daemon (void) if (proc_id != ((pid_t) 0)) { + if (close(unnamed_pipe[1]) == -1) + { + RELABSD_ERROR + ( + "Unable to close writing end of an unnamed pipe during the daemon" + " creation process: %s.", + strerror(errno) + ); + } + /* 8/ First child process exits *****************************************/ - exit(); + exit(0); } /* 9/ /dev/null for standard input/outputs *********************************/ + /* TODO. */ /* 10/ reset umask to 0 ****************************************************/ + /* Can't fail, returns previous mask. */ + (void) umask(0); /* 11/ Set current directory to / ******************************************/ errno = 0; @@ -110,6 +178,13 @@ int relabsd_server_create_daemon (void) if (chdir("/") == -1) { // Can't print an error message at that point though... + RELABSD_FATAL + ( + "Step 11 of the daemon creation process, fork(), failed: %s.", + strerror(errno) + ); + + /* TODO: boop main process. */ return -1; } @@ -117,10 +192,30 @@ int relabsd_server_create_daemon (void) /* Don't want to limit to a single instance. */ /* 13/ Drop privileges *****************************************************/ + /* We need those. */ /* 14/ Signal completion ***************************************************/ + if (write(unnamed_pipe[0], (void *) "!", (size_t) 1) == -1) + { + RELABSD_ERROR + ( + "Unable to write to writing end of an unnamed pipe during the daemon" + " creation process: %s.", + strerror(errno) + ); + } /* Step 15 is done on the very first process. */ + if (close(unnamed_pipe[1]) == -1) + { + RELABSD_ERROR + ( + "Unable to close writing end of an unnamed pipe during the daemon" + " creation process: %s.", + strerror(errno) + ); + } + return 0; } diff --git a/src/server/main_loop.c b/src/server/main_loop.c deleted file mode 100644 index 7db1423..0000000 --- a/src/server/main_loop.c +++ /dev/null @@ -1,165 +0,0 @@ -#include -#include -#include -#include -#include - -#include "pervasive.h" -#include "error.h" -#include "config.h" -#include "input.h" -#include "relabsd_device.h" - -static int RELABSD_RUN = 1; - -static void interrupt (int unused_mandatory_parameter) -{ - RELABSD_RUN = 0; - - RELABSD_S_WARNING("Interrupted, will exit at the next input device event."); -} - -static void handle_relative_axis_event -( - struct relabsd_config * const conf, - const struct relabsd_device * const dev, - unsigned int const input_type, - unsigned int const input_code, - int value -) -{ - unsigned int abs_code; - enum relabsd_axis rad_code; - - rad_code = relabsd_axis_convert_evdev_rel(input_code, &abs_code); - - switch (relabsd_config_filter(conf, rad_code, &value)) - { - case -1: - /* 'conf' doesn't want the event to be transmitted. */ - break; - - case 0: - /* 'conf' wants the event to be transmitted as is. */ - relabsd_device_write_evdev_event(dev, input_type, input_code, value); - break; - - case 1: - /* 'conf' allows the value to be emitted */ - relabsd_device_write_evdev_event(dev, EV_ABS, abs_code, value); - break; - } -} - -static void convert_input -( - struct relabsd_config * const conf, - struct relabsd_input * const input, - const struct relabsd_device * const dev -) -{ - unsigned int input_type, input_code; - int value; - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Handling input events..."); - - input->timed_out = 1; - - while (RELABSD_RUN == 1) - { - if (conf->enable_timeout) - { - switch (relabsd_input_wait_for_next_event(input, conf)) - { - case 1: - input->timed_out = 0; - break; - - case 0: - relabsd_device_set_axes_to_zero(dev, conf); - input->timed_out = 1; - break; - - case -1: - continue; - } - } - - if (relabsd_input_read(input, &input_type, &input_code, &value) < 0) - { - /* - * The next event should not be retransmitted, or some kind of error - * happened. - */ - /* TODO: error handling. */ - continue; - } - - if (input_type == EV_REL) - { - /* We might have to convert the event. */ - handle_relative_axis_event(conf, dev, input_type, input_code, value); - } - else - { - /* Any other event is retransmitted as is. */ - relabsd_device_write_evdev_event(dev, input_type, input_code, value); - } - } -} - -static int set_signal_handlers () -{ - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Setting signal handlers."); - - if (signal(SIGINT, interrupt) == SIG_ERR) - { - RELABSD_S_FATAL("Unable to set the SIGINT signal handler."); - - return -1; - } - - return 0; -} - -/* -int main (int argc, char ** argv) -{ - struct relabsd_config conf; - struct relabsd_input input; - struct relabsd_device dev; - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "relabsd started."); - - if (set_signal_handlers() < 0) - { - return -1; - } - - if (relabsd_config_parse(&conf, argc, argv) < 0) - { - return -2; - } - - if (relabsd_input_open(&input, &conf) < 0) - { - return -3; - } - - if (relabsd_device_create(&dev, &conf) < 0) - { - return -4; - } - - convert_input(&conf, &input, &dev); - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Terminating..."); - - relabsd_device_destroy(&dev); - relabsd_input_close(&input); - - RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Done."); - - return 0; -} -*/ diff --git a/src/server/server.c b/src/server/server.c index debeb91..ddd9bdf 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -33,7 +33,7 @@ int initialize ( relabsd_virtual_device_create ( - + relabsd_parameters_get_virtual_device_name(params), &(server->virtual_device) ) < 0 @@ -56,14 +56,23 @@ int initialize return -3; } + if (relabsd_parameters_get_communication_node(params) != ((char *) NULL)) + { + relabsd_server_create_communication_thread(&server); + } + return 0; } void finalize (struct relabsd_server server [const static 1]) { - if (relabsd_parameters_get_communication_node(params) != ((...) NULL)) + if + ( + relabsd_parameters_get_communication_node(server->parameters) + != ((char *) NULL) + ) { - relabsd_server_join_communication_node(&server); + relabsd_server_join_communication_thread(&server); } relabsd_virtual_device_destroy(&(server->virtual_device)); -- cgit v1.2.3-70-g09d2