aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--src/mds-base.c24
-rw-r--r--src/mds-base.h15
-rw-r--r--src/mds-kkbd.c115
-rw-r--r--src/mds-kkbd.h8
-rw-r--r--src/mds-registry/signals.c42
-rw-r--r--src/mds-server/signals.c42
7 files changed, 141 insertions, 107 deletions
diff --git a/TODO b/TODO
index ca20837..e75eb34 100644
--- a/TODO
+++ b/TODO
@@ -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);
- }
-}
-