| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-12-23 15:44:19 +0100 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-12-23 15:44:19 +0100 | 
| commit | 390576c3839ee7abb845e27b7267de45495e6b2f (patch) | |
| tree | c481c37c868ccc65a3476f60b17369b21a90b79b /src/server | |
| parent | 4355548f79375a62bb5e3bb5695190d48e4c0bc3 (diff) | |
Starting to turn relabsd into a proper daemon...
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/daemon.c | 126 | ||||
| -rw-r--r-- | src/server/main_loop.c | 165 | ||||
| -rw-r--r-- | src/server/server.c | 113 | 
3 files changed, 404 insertions, 0 deletions
| diff --git a/src/server/daemon.c b/src/server/daemon.c new file mode 100644 index 0000000..7b8e736 --- /dev/null +++ b/src/server/daemon.c @@ -0,0 +1,126 @@ +/**** POSIX *******************************************************************/ +#include <sys/types.h> + +#include <unistd.h> + +/**** RELABSD *****************************************************************/ +#include <relabsd/config.h> +#include <relabsd/debug.h> +#include <relabsd/server.h> + +#include <relabsd/config/parameters.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +/* + * Daemon creation function made using the instructions for old-school daemons + * at https://www.freedesktop.org/software/systemd/man/daemon.html + * Only meant to be used before things really start. This won't properly create + * a daemon on an already running server instance with a virtual device and so + * on... + */ +int relabsd_server_create_daemon (void) +{ +   pid_t proc_id; + +   /* 1/ Close all open file descriptors ... **********************************/ +   /* None were opened at this point. */ + +   /* 2/ Reset all signal handlers ... ****************************************/ +   /* Those were not modified at this point. */ + +   /* 3/ Reset the signal mask using sigprocmask() ****************************/ +   /* Not modified at this point. */ + +   /* 4/ Sanitize the environment block ... ***********************************/ +   /* What? */ + +   /* 5/ fork() ***************************************************************/ +   errno = 0; +   proc_id = fork(); + +   if (proc_id == ((pid_t) -1)) +   { +      RELABSD_FATAL +      ( +         "Step 5 of the daemon creation process, fork(), failed: %s.", +         strerror(errno) +      ); + +      return -1; +   } + +   if (proc_id != ((pid_t) 0)) +   { +      /* Awaiting step 14...*/ +      /* TODO: insert unnamed pipe */ +      /* 15/ Original process exits *******************************************/ +      exit(); +   } + +   /* 6/ setsid() *************************************************************/ +   errno = 0; + +   proc_id = setsid(); + +   if (proc_id == ((pid_t) -1)) +   { +      RELABSD_FATAL +      ( +         "Step 6 of the daemon creation process, setsid(), failed: %s.", +         strerror(errno) +      ); + +      return -1; +   } + +   /* 7/ fork() again *********************************************************/ +   errno = 0; +   proc_id = fork(); + +   if (proc_id == ((pid_t) -1)) +   { +      RELABSD_FATAL +      ( +         "Step 5 of the daemon creation process, fork(), failed: %s.", +         strerror(errno) +      ); + +      return -1; +   } + +   if (proc_id != ((pid_t) 0)) +   { +      /* 8/ First child process exits *****************************************/ +      exit(); +   } + +   /* 9/ /dev/null for standard input/outputs *********************************/ + +   /* 10/ reset umask to 0 ****************************************************/ + +   /* 11/ Set current directory to / ******************************************/ +   errno = 0; + +   if (chdir("/") == -1) +   { +      // Can't print an error message at that point though... +      return -1; +   } + +   /* 12/ lock file using PID to assert single instance ***********************/ +   /* Don't want to limit to a single instance. */ + +   /* 13/ Drop privileges *****************************************************/ + +   /* 14/ Signal completion ***************************************************/ + +   /* Step 15 is done on the very first process. */ + +   return 0; +} diff --git a/src/server/main_loop.c b/src/server/main_loop.c new file mode 100644 index 0000000..7db1423 --- /dev/null +++ b/src/server/main_loop.c @@ -0,0 +1,165 @@ +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> + +#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 new file mode 100644 index 0000000..debeb91 --- /dev/null +++ b/src/server/server.c @@ -0,0 +1,113 @@ +/**** RELABSD *****************************************************************/ +#include <relabsd/config.h> +#include <relabsd/debug.h> +#include <relabsd/server.h> + +#include <relabsd/config/parameters.h> + +/******************************************************************************/ +/**** LOCAL FUNCTIONS *********************************************************/ +/******************************************************************************/ +int initialize +( +   struct relabsd_server server [const restrict static 1], +   struct relabsd_parameters params [const static 1] +) +{ +   server->parameters = params; + +   if +   ( +      relabsd_physical_device_open +      ( +         relabsd_parameters_get_physical_device_name(params), +         &(server->physical_device) +      ) +      < 0 +   ) +   { +      return -1; +   } + +   if +   ( +      relabsd_virtual_device_create +      ( + +         &(server->virtual_device) +      ) +      < 0 +   ) +   { +      relabsd_physical_device_close(&(server->physical_device)); + +      return -2; +   } + +   if +   ( +      (relabsd_parameters_get_communication_node(params) != ((...) NULL)) +      && (relabsd_server_spawn_communication_node(server) < 0) +   ) +   { +      relabsd_virtual_device_destroy(&(server->virtual_device)); +      relabsd_physical_device_close(&(server->physical_device)); + +      return -3; +   } + +   return 0; +} + +void finalize (struct relabsd_server server [const static 1]) +{ +   if (relabsd_parameters_get_communication_node(params) != ((...) NULL)) +   { +      relabsd_server_join_communication_node(&server); +   } + +   relabsd_virtual_device_destroy(&(server->virtual_device)); +   relabsd_physical_device_close(&(server->physical_device)); + +   return 0; +} + +/******************************************************************************/ +/**** EXPORTED FUNCTIONS ******************************************************/ +/******************************************************************************/ +int relabsd_server +( +   const int argc, +   const char * const argv [const restrict static argc], +   struct relabsd_parameters params [const static 1] +) +{ +   struct relabsd_server server; + +   RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Started server mode."); + +   if (relabsd_parameters_parse_options(argc, argv, params) < 0) +   { +      return -1; +   } + +   if +   ( +      (relabsd_parameters_run_as_daemon(params)) +      && (relabsd_server_create_daemon() < 0) +   ) +   { +      return -2; +   } + +   (void) initialize(&server, params); + +   (void) relabsd_server_conversion_loop(&server); + +   finalize(&server); + + +   RELABSD_S_DEBUG(RELABSD_DEBUG_PROGRAM_FLOW, "Completed server mode."); + +   return 0; +} | 


