diff options
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | TODO | 26 | ||||
| -rw-r--r-- | src/mds-echo.c | 262 | ||||
| -rw-r--r-- | src/mds-echo.h | 40 | ||||
| -rwxr-xr-x | test.d/mdsinitrc | 4 | 
5 files changed, 336 insertions, 3 deletions
| @@ -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 $@) @@ -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 | 
