diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/mds-base.c | 24 | ||||
-rw-r--r-- | src/mds-base.h | 15 | ||||
-rw-r--r-- | src/mds-kkbd.c | 115 | ||||
-rw-r--r-- | src/mds-kkbd.h | 8 | ||||
-rw-r--r-- | src/mds-registry/signals.c | 42 | ||||
-rw-r--r-- | src/mds-server/signals.c | 42 |
7 files changed, 141 insertions, 107 deletions
@@ -70,4 +70,6 @@ Optimise use of mutexe by replace them with rwlocks Listen for `Command: reregister` Register protocols Make it possible to forbid unauthorised servers for listening, needed for secure password fields + I guess we can let servers create their own abstract sockets, report them to mdsinitrc and + let mdsinitrc export appropriate environment variables. diff --git a/src/mds-base.c b/src/mds-base.c index 95eb4e0..572202e 100644 --- a/src/mds-base.c +++ b/src/mds-base.c @@ -265,11 +265,29 @@ void received_noop(int signo) } +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsuggest-attribute=const" +/** + * This function should be implemented by the actual server implementation + * if the server is multi-threaded + * + * Send a singal to all threads except the current thread + * + * @param signo The signal + */ +void __attribute__((weak)) signal_all(int signo) +{ + (void) signo; +} +# pragma GCC diagnostic pop + + /** * This function is called when a signal that * signals the server to re-exec has been received * - * When this function is invoked, it should set `reexecing` to a non-zero value + * When this function is invoked, it should set `reexecing` and + * `terminating` to a non-zero value * * @param signo The signal that has been received */ @@ -278,8 +296,9 @@ void __attribute__((weak)) received_reexec(int signo) (void) signo; if (reexecing == 0) { - reexecing = 1; + reexecing = terminating = 1; eprint("re-exec signal received."); + signal_all(signo); } } @@ -299,6 +318,7 @@ void __attribute__((weak)) received_terminate(int signo) { terminating = 1; eprint("terminate signal received."); + signal_all(signo); } } diff --git a/src/mds-base.h b/src/mds-base.h index 68feb32..2dac449 100644 --- a/src/mds-base.h +++ b/src/mds-base.h @@ -180,21 +180,26 @@ void received_noop(int signo) __attribute__((weak, const)); /** * This function should be implemented by the actual server implementation - * if the server is multithreaded + * if the server is multi-threaded * + * Send a singal to all threads except the current thread + * + * @param signo The signal + */ +void signal_all(int signo) __attribute__((weak)); + +/** * This function is called when a signal that * signals the server to re-exec has been received * - * When this function is invoked, it should set `reexecing` to a non-zero value + * When this function is invoked, it should set `reexecing` and + * `terminating` to a non-zero value * * @param signo The signal that has been received */ void received_reexec(int signo); /* __attribute__((weak)) */ /** - * This function should be implemented by the actual server implementation - * if the server is multithreaded - * * This function is called when a signal that * signals the server to re-exec has been received * diff --git a/src/mds-kkbd.c b/src/mds-kkbd.c index afa9cac..c408f54 100644 --- a/src/mds-kkbd.c +++ b/src/mds-kkbd.c @@ -29,6 +29,7 @@ #include <unistd.h> #include <sys/ioctl.h> #include <linux/kd.h> +#include <pthread.h> #define reconnect_to_display() -1 /* TODO */ @@ -131,6 +132,21 @@ static int scancode_buf[3] = { 0, 0, 0 }; */ static int scancode_ptr = 0; +/** + * Message buffer for `send_key` + */ +static char* key_send_buffer = NULL; + +/** + * The keyboard listener thread + */ +static pthread_t kbd_thread; + +/** + * Whether `kbd_thread` has started + */ +static int kbd_thread_started = 0; + /** @@ -172,6 +188,7 @@ int initialise_server(void) fail_if (server_initialised()); stage = 0; fail_if (mds_message_initialise(&received)); + fail_if (xmalloc(key_send_buffer, 111, char)); return 0; @@ -334,19 +351,17 @@ int __attribute__((const)) reexec_failure_recover(void) */ int master_loop(void) { - int rc = 1; + int rc = 1, joined = 0; + void* kbd_ret; + + fail_if ((errno = pthread_create(&kbd_thread, NULL, keyboard_loop, NULL))); - while (!reexecing && !terminating) - if (fetch_keys() < 0) - if (errno != EINTR) - goto pfail; - /* while (!reexecing && !terminating) { int r = mds_message_read(&received, socket_fd); if (r == 0) { - if (r = 0, r == 0) \/* TODO handle_message() *\/ + if (r = 0, r == 0) /* TODO handle_message() */ continue; } @@ -368,9 +383,10 @@ int master_loop(void) goto fail; connected = 1; } - */ - rc = 0; + joined = 1; + fail_if ((errno = pthread_join(kbd_thread, &kbd_ret))); + rc = kbd_ret == NULL ? 0 : 1; goto fail; pfail: xperror(*argv); @@ -378,12 +394,59 @@ int master_loop(void) if (!rc && reexecing) return 0; mds_message_destroy(&received); - free(mapping); + if ((!joined) && (errno = pthread_join(kbd_thread, NULL))) + xperror(*argv); return rc; } /** + * The keyboard listener thread's main function + * + * @param data Input data + * @return Output data + */ +void* keyboard_loop(void* data) +{ + (void) data; + + kbd_thread_started = 1; + + while (!reexecing && !terminating) + if (fetch_keys() < 0) + if (errno != EINTR) + goto pfail; + + free(mapping); + return NULL; + + pfail: + xperror(*argv); + free(mapping); + raise(SIGTERM); + return (void*)1024; +} + + +/** + * Send a singal to all threads except the current thread + * + * @param signo The signal + */ +void signal_all(int signo) +{ + pthread_t current_thread = pthread_self(); + + if (pthread_equal(current_thread, master_thread) == 0) + pthread_kill(master_thread, signo); + + if (kbd_thread_started) + if (pthread_equal(current_thread, kbd_thread) == 0) + pthread_kill(kbd_thread, signo); +} + + +/** * Send a full message even if interrupted * * @param message The message to send @@ -538,16 +601,31 @@ int send_key(int* restrict scancode, int trio) if ((size_t)keycode < mapping_size) keycode = mapping[keycode]; - printf("Command: key-sent\n"); if (trio) - printf("Scancode: %i %i %i\n", scancode[0], scancode[1], scancode[2]); + sprintf(key_send_buffer, + "Command: key-sent\n" + "Scancode: %i %i %i\n" + "Keycode: %i\n" + "Released: %s\n" + "Keyboard: kernel\n" + "Message ID: " PRIi32 "\n" + "\n", + scancode[0], scancode[1], scancode[2], keycode, + released ? "yes" : "no", message_id); else - printf("Scancode: %i\n", scancode[0]); - printf("Keycode: %i\n", keycode); - printf("Released: %s\n", released ? "yes" : "no"); - printf("Keyboard: kernel\n\n"); + sprintf(key_send_buffer, + "Command: key-sent\n" + "Scancode: %i\n" + "Keycode: %i\n" + "Released: %s\n" + "Keyboard: kernel\n" + "Message ID: " PRIi32 "\n" + "\n", + scancode[0], keycode, + released ? "yes" : "no", message_id); - return 0; + message_id = message_id == INT32_MAX ? 0 : (message_id + 1); + return full_send(key_send_buffer, strlen(key_send_buffer)); } @@ -580,9 +658,10 @@ int fetch_keys(void) #ifdef DEBUG if ((c & 0x7F) == 1) /* Exit with ESCAPE, ESCAPE, ESCAPE */ { - if (++consecutive_escapes >= 6) + if (++consecutive_escapes >= 2 * 3) { raise(SIGTERM); + errno = 0; break; } } diff --git a/src/mds-kkbd.h b/src/mds-kkbd.h index 3fa7eca..05875b9 100644 --- a/src/mds-kkbd.h +++ b/src/mds-kkbd.h @@ -23,6 +23,14 @@ /** + * The keyboard listener thread's main function + * + * @param data Input data + * @return Output data + */ +void* keyboard_loop(void* data); + +/** * Send a full message even if interrupted * * @param message The message to send diff --git a/src/mds-registry/signals.c b/src/mds-registry/signals.c index 7d1f5b4..954c12b 100644 --- a/src/mds-registry/signals.c +++ b/src/mds-registry/signals.c @@ -25,9 +25,7 @@ #include <libmdsserver/linked-list.h> #include <libmdsserver/macros.h> -#include <stdio.h> #include <pthread.h> -#include <errno.h> @@ -36,7 +34,7 @@ * * @param signo The signal */ -static void signal_all(int signo) +void signal_all(int signo) { pthread_t current_thread; ssize_t node; @@ -56,41 +54,3 @@ static void signal_all(int signo) ); } - -/** - * This function is called when a signal that - * signals the server to re-exec has been received - * - * When this function is invoked, it should set `reexecing` to a non-zero value - * - * @param signo The signal that has been received - */ -void received_reexec(int signo) -{ - if (reexecing == 0) - { - terminating = reexecing = 1; - eprint("re-exec signal received."); - signal_all(signo); - } -} - - -/** - * This function is called when a signal that - * signals the server to re-exec has been received - * - * When this function is invoked, it should set `terminating` to a non-zero value - * - * @param signo The signal that has been received - */ -void received_terminate(int signo) -{ - if (terminating == 0) - { - terminating = 1; - eprint("terminate signal received."); - signal_all(signo); - } -} - diff --git a/src/mds-server/signals.c b/src/mds-server/signals.c index 325fa35..ed2fba2 100644 --- a/src/mds-server/signals.c +++ b/src/mds-server/signals.c @@ -22,9 +22,7 @@ #include <libmdsserver/linked-list.h> #include <libmdsserver/macros.h> -#include <stdio.h> #include <pthread.h> -#include <errno.h> /** @@ -32,7 +30,7 @@ * * @param signo The signal */ -static void signal_all(int signo) +void signal_all(int signo) { pthread_t current_thread; ssize_t node; @@ -52,41 +50,3 @@ static void signal_all(int signo) ); } - -/** - * This function is called when a signal that - * signals the server to re-exec has been received - * - * When this function is invoked, it should set `reexecing` to a non-zero value - * - * @param signo The signal that has been received - */ -void received_reexec(int signo) -{ - if (reexecing == 0) - { - terminating = reexecing = 1; - eprint("re-exec signal received."); - signal_all(signo); - } -} - - -/** - * This function is called when a signal that - * signals the server to re-exec has been received - * - * When this function is invoked, it should set `terminating` to a non-zero value - * - * @param signo The signal that has been received - */ -void received_terminate(int signo) -{ - if (terminating == 0) - { - terminating = 1; - eprint("terminate signal received."); - signal_all(signo); - } -} - |