Index: include/libroar/socket.h
===================================================================
--- include/libroar/socket.h	(revision 5364)
+++ include/libroar/socket.h	(revision 5369)
@@ -62,5 +62,4 @@
 
 int roar_socket_open       (int mode, int type, const char * host, int port);
-int roar_socket_open_fork  (int mode, const char * host, int port);
 int roar_socket_open_file  (int mode, const char * host, int port) _LIBROAR_ATTR_TO_STATIC;
 int roar_socket_open_proxy (int mode, int type, const char * host, int port, const char * proxy_type) _LIBROAR_ATTR_TO_STATIC;
Index: libroar/basic.c
===================================================================
--- libroar/basic.c	(revision 5368)
+++ libroar/basic.c	(revision 5369)
@@ -36,4 +36,94 @@
 #include "libroar.h"
 
+static int _start_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) {
+#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
+ enum {
+  NORMAL = 0,
+  SYSTEM = 1
+ } mode = NORMAL;
+ const char * daemonimage = NULL;
+ int socks[2];
+ int r;
+ char fhstr[12];
+
+ if ( !strncmp(server, "+fork=", 6) ) {
+  server += 6;
+  if ( server[0] == 0 ) {
+   // no special case, we just ignore it.
+  } else if ( server[0] == 'd' && server[1] == ':' ) {
+   server += 2;
+   daemonimage = server;
+  } else if ( server[0] == '!' ) {
+   server += 1;
+   daemonimage = server;
+   mode = SYSTEM;
+  } else {
+   roar_err_set(ROAR_ERROR_ILLSEQ);
+   return -1;
+  }
+ }
+
+ // TODO: FIXME: we should move this into the config structure.
+ if ( daemonimage == NULL )
+  daemonimage = getenv("ROAR_DAEMONIMAGE");
+
+ if ( daemonimage == NULL || *daemonimage == 0 )
+  daemonimage = "roard";
+
+ if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) {
+  roar_err_from_errno();
+  return -1;
+ }
+
+ r = fork();
+
+ if ( r == -1 ) { // error!
+  roar_err_from_errno();
+  ROAR_ERR("roar_socket_open_fork(*): Can not fork: %s", strerror(errno));
+  close(socks[0]);
+  close(socks[1]);
+  return -1;
+ } else if ( r == 0 ) { // we are the child
+  close(socks[0]);
+
+  close(ROAR_STDIN ); // we do not want roard to have any standard input
+  close(ROAR_STDOUT); // STDOUT is also not needed, so we close it,
+                      // but STDERR we keep open for error messages.
+
+  snprintf(fhstr, sizeof(fhstr), "%i", socks[1]);
+
+  switch (mode) {
+   case NORMAL:
+     execlp(daemonimage, daemonimage, "--no-listen", "--client-fh", fhstr, (_LIBROAR_GOOD_CAST char*)NULL);
+    break;
+   case SYSTEM:
+     dup2(socks[1], ROAR_STDIN );
+     dup2(socks[1], ROAR_STDOUT);
+     execl("/bin/sh", "/bin/sh", "-c", daemonimage, (_LIBROAR_GOOD_CAST char*)NULL);
+     execlp("sh", "sh", "-c", daemonimage, (_LIBROAR_GOOD_CAST char*)NULL);
+    break;
+  }
+
+  // we are still alive?
+  ROAR_ERR("roar_socket_open_fork(*): alive after exec(), that's bad!");
+  _exit(1);
+ } else { // we are the parent
+  close(socks[1]);
+  if ( roar_vio_open_fh_socket(con->viocon, socks[0]) == -1 ) {
+   close(socks[0]);
+   return -1;
+  } else {
+   con->flags |= ROAR_CON_FLAGS_VIO;
+  }
+  return 0;
+ }
+
+ return -1;
+#else
+ ROAR_ERR("roar_socket_open_fork(*): There is no UNIX Domain Socket support in win32, download a real OS.");
+ return -1;
+#endif
+}
+
 static int _connect_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) {
 #if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT)
@@ -61,4 +151,6 @@
   con->flags |= ROAR_CON_FLAGS_VIO;
   return 0;
+ } else if ( !strcmp(server, "+fork") || !strncmp(server, "+fork=", 6) ) {
+  return _start_server(con, server, type, flags, timeout);
  }
 
@@ -288,6 +380,7 @@
  } else {
   /* connect via (char*)server */
-  if ( _connect_server(con, server, -1, flags, timeout) == 0 )
-   return 0;
+  if ( _connect_server(con, server, -1, flags, timeout) != 0 )
+   return -1;
+  return 0;
  }
 
Index: libroar/socket.c
===================================================================
--- libroar/socket.c	(revision 5364)
+++ libroar/socket.c	(revision 5369)
@@ -795,5 +795,6 @@
 #endif
  } else if ( type == ROAR_SOCKET_TYPE_FORK ) {
-  return roar_socket_open_fork(mode, host, port);
+  roar_err_set(ROAR_ERROR_INVAL);
+  return -1;
  } else if ( type == ROAR_SOCKET_TYPE_FILE ) {
   return roar_socket_open_file(mode, host, port);
@@ -817,57 +818,4 @@
 
  return fh;
-}
-
-int roar_socket_open_fork  (int mode, const char * host, int port) {
-#if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
- char * daemonimage;
- int socks[2];
- int r;
- char fhstr[8];
-
- if ( mode == MODE_LISTEN )
-  return -1;
-
- // TODO: FIXME: we should move this into the config structure.
- daemonimage = getenv("ROAR_DAEMONIMAGE");
-
- if ( daemonimage == NULL || *daemonimage == 0 )
-  daemonimage = "roard";
-
- if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) {
-  return -1;
- }
-
- r = fork();
-
- if ( r == -1 ) { // error!
-  ROAR_ERR("roar_socket_open_fork(*): Can not fork: %s", strerror(errno));
-  close(socks[0]);
-  close(socks[1]);
-  return -1;
- } else if ( r == 0 ) { // we are the child
-  close(socks[0]);
-
-  close(ROAR_STDIN ); // we do not want roard to have any standard input
-  close(ROAR_STDOUT); // STDOUT is also not needed, so we close it,
-                      // but STDERR we keep open for error messages.
-
-  snprintf(fhstr, 7, "%i", socks[1]);
-
-  execlp(daemonimage, daemonimage, "--no-listen", "--client-fh", fhstr, (_LIBROAR_GOOD_CAST char*)NULL);
-
-  // we are still alive?
-  ROAR_ERR("roar_socket_open_fork(*): alive after exec(), that's bad!");
-  _exit(1);
- } else { // we are the parent
-  close(socks[1]);
-  return socks[0];
- }
-
- return -1;
-#else
- ROAR_ERR("roar_socket_open_fork(*): There is no UNIX Domain Socket support in win32, download a real OS.");
- return -1;
-#endif
 }
 
