aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-06-08 10:24:48 +0200
committerMattias Andrée <maandree@operamail.com>2014-06-08 10:24:48 +0200
commit0210ede88f9f10ef042dc37d7494c84f3f99a634 (patch)
treeb47f8422dae075473b803e1cb37e7b82016df911
parentwhitespace (diff)
downloadmds-0210ede88f9f10ef042dc37d7494c84f3f99a634.tar.gz
mds-0210ede88f9f10ef042dc37d7494c84f3f99a634.tar.bz2
mds-0210ede88f9f10ef042dc37d7494c84f3f99a634.tar.xz
beginning of echo server
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--Makefile7
-rw-r--r--TODO26
-rw-r--r--src/mds-echo.c262
-rw-r--r--src/mds-echo.h40
-rwxr-xr-xtest.d/mdsinitrc4
5 files changed, 336 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index ec70381..1a3c248 100644
--- a/Makefile
+++ b/Makefile
@@ -72,11 +72,14 @@ C_FLAGS = $(OPTIMISE) $(WARN) -std=$(STD) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
# Object files for the libary
LIBOBJ = linked-list hash-table fd-table mds-message util
+# Servers and utilities.
+SERVERS = mds mds-respawn mds-server mds-echo
+
# Build rules.
.PHONY: all
-all: obj/mds-base.o bin/mds bin/mds-respawn bin/mds-server bin/libmdsserver.so
+all: obj/mds-base.o $(foreach S,$(SERVERS),bin/$(S)) bin/libmdsserver.so
MDS_SERVER_OBJ_ = mds-server interception-condition client multicast \
@@ -94,7 +97,7 @@ endif
bin/%: obj/%.o obj/mds-base.o bin/libmdsserver.so
mkdir -p $(shell dirname $@)
- $(CC) $(C_FLAGS) -o $@ $(LDS) $< obj/mds-base.o
+ $(CC) $(C_FLAGS) -o $@ $(LDS) $(LDS_$*) $< obj/mds-base.o
bin/mds: obj/mds.o bin/libmdsserver.so
mkdir -p $(shell dirname $@)
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..6515768
--- /dev/null
+++ b/TODO
@@ -0,0 +1,26 @@
+Missing servers:
+
+ xmds Translation from X to mds
+ wmds Translation from Wayland to mds
+ mmds Translation from Mir to mds
+ mdsx Translation from mds to X
+ mdsw Translation from mds to Wayland
+ mdsm Translation from mds to Mir
+ hwgamma Hardware implementation of gamma ramps
+ swgamma Software implementation of gamma ramps
+ hwcursor Hardware cursor
+ swcursor Software cursor
+ cursorgamma Fixes gamma ramps for cursors
+ coopgamma Enables multiple gamma servers
+ inet Network enabled display server
+ remote Bind to a remote display server
+ fb Framebuffer presenter
+ clipboard Clipboard
+ kkbd Keyboard input from kernel
+ kbd Keyboard input
+ rat Rat input
+ compositor Composites the display
+ crtc CRTC identifier
+ seat Seat sandboxing
+ dri DRI output
+
diff --git a/src/mds-echo.c b/src/mds-echo.c
new file mode 100644
index 0000000..7b1a0ac
--- /dev/null
+++ b/src/mds-echo.c
@@ -0,0 +1,262 @@
+/**
+ * mds — A micro-display server
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "mds-echo.h"
+
+#include <libmdsserver/macros.h>
+#include <libmdsserver/util.h>
+#include <libmdsserver/mds-message.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#define reconnect_to_display() -1 /* TODO */
+
+
+
+#define MDS_ECHO_VARS_VERSION 0
+
+
+
+/**
+ * This variable should declared by the actual server implementation.
+ * It must be configured before `main` is invoked.
+ *
+ * This tells the server-base how to behave
+ */
+server_characteristics_t server_characteristics =
+ {
+ .require_privileges = 0,
+ .require_display = 1,
+ .require_respawn_info = 1,
+ .sanity_check_argc = 1
+ };
+
+
+
+/**
+ * Value of the ‘Message ID’ header for the next message
+ */
+static int32_t message_id = 1;
+
+/**
+ * Buffer for received messages
+ */
+static mds_message_t received;
+
+/**
+ * Whether the server is connected to the display
+ */
+static int connected = 1;
+
+
+
+/**
+ * This function will be invoked before `initialise_server` (if not re-exec:ing)
+ * or before `unmarshal_server` (if re-exec:ing)
+ *
+ * @return Non-zero on error
+ */
+int __attribute__((const)) preinitialise_server(void)
+{
+ return 0;
+}
+
+
+/**
+ * This function should initialise the server,
+ * and it not invoked after a re-exec.
+ *
+ * @return Non-zero on error
+ */
+int initialise_server(void)
+{
+ const char* message =
+ "Command: intercept\n"
+ "Message ID: 0\n"
+ "Length: 13\n"
+ "\n"
+ "Command: echo";
+ size_t length = strlen(message);
+ size_t sent;
+
+ while (length > 0)
+ {
+ sent = send_message(socket_fd, message, length);
+ if (sent > length)
+ {
+ eprint("Sent more of a message than exists in the message, aborting.");
+ return 1;
+ }
+ else if ((sent < length) && (errno != EINTR))
+ {
+ perror(*argv);
+ return 1;
+ }
+ message += sent;
+ length -= sent;
+ }
+
+ mds_message_initialise(&received);
+ return 0;
+}
+
+
+/**
+ * This function will be invoked after `initialise_server` (if not re-exec:ing)
+ * or after `unmarshal_server` (if re-exec:ing)
+ *
+ * @return Non-zero on error
+ */
+int postinitialise_server(void)
+{
+ if (connected)
+ return 0;
+
+ if (reconnect_to_display())
+ {
+ mds_message_destroy(&received);
+ return 1;
+ }
+ connected = 1;
+ return 0;
+}
+
+
+/**
+ * Calculate the number of bytes that will be stored by `marshal_server`
+ *
+ * On failure the program should `abort()` or exit by other means.
+ * However it should not be possible for this function to fail.
+ *
+ * @return The number of bytes that will be stored by `marshal_server`
+ */
+size_t marshal_server_size(void)
+{
+ return 2 * sizeof(int) + sizeof(int32_t) + mds_message_marshal_size(&received);
+}
+
+
+/**
+ * Marshal server implementation specific data into a buffer
+ *
+ * @param state_buf The buffer for the marshalled data
+ * @return Non-zero on error
+ */
+int marshal_server(char* state_buf)
+{
+ buf_set_next(state_buf, int, MDS_ECHO_VARS_VERSION);
+ buf_set_next(state_buf, int, connected);
+ buf_set_next(state_buf, int32_t, message_id);
+ mds_message_marshal(&received, state_buf);
+ return 0;
+}
+
+
+/**
+ * Unmarshal server implementation specific data and update the servers state accordingly
+ *
+ * On critical failure the program should `abort()` or exit by other means.
+ * That is, do not let `reexec_failure_recover` run successfully, if it unrecoverable
+ * error has occurred or one severe enough that it is better to simply respawn.
+ *
+ * @param state_buf The marshalled data that as not been read already
+ * @return Non-zero on error
+ */
+int unmarshal_server(char* state_buf)
+{
+ int r;
+ /* buf_get_next(state_buf, int, MDS_ECHO_VARS_VERSION); */
+ buf_next(state_buf, int, 1);
+ buf_get_next(state_buf, int, connected);
+ buf_get_next(state_buf, int32_t, message_id);
+ r = mds_message_unmarshal(&received, state_buf);
+ if (r)
+ mds_message_destroy(&received);
+ return r;
+}
+
+
+/**
+ * Attempt to recover from a re-exec failure that has been
+ * detected after the server successfully updated it execution image
+ *
+ * @return Non-zero on error
+ */
+int __attribute__((const)) reexec_failure_recover(void)
+{
+ return -1;
+}
+
+
+/**
+ * Perform the server's mission
+ *
+ * @return Non-zero on error
+ */
+int master_loop(void)
+{
+ while (!reexecing && !terminating)
+ {
+ int r = mds_message_read(&received, socket_fd);
+ if (r == 0)
+ {
+ r = echo_message();
+ if (r == 0)
+ continue;
+ }
+ if (r == -2)
+ {
+ eprint("corrupt message received, aborting.");
+ goto fail;
+ }
+ else if (errno == EINTR)
+ continue;
+ else if (errno != ECONNRESET)
+ goto pfail;
+
+ eprint("lost connection to server.");
+ mds_message_destroy(&received);
+ mds_message_initialise(&received);
+ connected = 0;
+ if (reconnect_to_display())
+ goto fail;
+ connected = 1;
+ }
+
+ mds_message_destroy(&received);
+ return 0;
+ pfail:
+ perror(*argv);
+ fail:
+ mds_message_destroy(&received);
+ return 1;
+}
+
+
+/**
+ * Echo the received message payload
+ *
+ * @return Zero on success -1 on error or interruption,
+ * errno will be set accordingly
+ */
+int echo_message(void)
+{
+ return 0; /* TODO */
+}
+
diff --git a/src/mds-echo.h b/src/mds-echo.h
new file mode 100644
index 0000000..83a6495
--- /dev/null
+++ b/src/mds-echo.h
@@ -0,0 +1,40 @@
+/**
+ * mds — A micro-display server
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MDS_MDS_ECHO_H
+#define MDS_MDS_ECHO_H
+
+
+#include "mds-base.h"
+
+
+/**
+ * Echo the received message
+ *
+ * @return Non-zero on error or interruption, errno will be
+ * set accordingly. Destroy the message on error,
+ * be aware that the reading could have been
+ * interrupted by a signal rather than canonical error.
+ * If -2 is returned errno will not have been set,
+ * -2 indicates that the message is malformated,
+ * which is a state that cannot be recovered from.
+ */
+int echo_message(void);
+
+
+#endif
+
diff --git a/test.d/mdsinitrc b/test.d/mdsinitrc
index aaa52a6..0c1f75f 100755
--- a/test.d/mdsinitrc
+++ b/test.d/mdsinitrc
@@ -28,7 +28,9 @@ if [ -z "${XDG_CONFIG_HOME}" ]; then
fi
mds-respawn --interval=10 \
{ sleep 4s } \
- { sleep 1m } &
+ { sleep 1m } \
+ { mds-echo } \
+ &
if which terminator 2>/dev/null >&2; then
exec terminator
else