Index: include/libroar/vio_pipe.h
===================================================================
--- include/libroar/vio_pipe.h	(revision 1301)
+++ include/libroar/vio_pipe.h	(revision 1304)
@@ -44,4 +44,6 @@
 #define ROAR_VIO_PIPE_TYPE_SOCKET     3
 
+#define ROAR_VIO_PIPE_S(self,stream)  ((self->s0) == (stream) ? 0 : 1)
+
 struct roar_vio_pipe {
  int refcount;
@@ -52,7 +54,15 @@
   int                  p[4];
  } b;
+ struct roar_vio_calls * s0;
 };
 
-int roar_vio_open_pipe (struct roar_vio_calls * s1, struct roar_vio_calls * s2, int type, int flags);
+int roar_vio_open_pipe (struct roar_vio_calls * s0, struct roar_vio_calls * s1, int type, int flags);
+int roar_vio_pipe_init (struct roar_vio_calls * s,  struct roar_vio_pipe * self, int flags);
+
+ssize_t roar_vio_pipe_read    (struct roar_vio_calls * vio, void *buf, size_t count);
+ssize_t roar_vio_pipe_write   (struct roar_vio_calls * vio, void *buf, size_t count);
+int     roar_vio_pipe_nonblock(struct roar_vio_calls * vio, int state);
+int     roar_vio_pipe_sync    (struct roar_vio_calls * vio);
+int     roar_vio_pipe_close   (struct roar_vio_calls * vio);
 
 #endif
Index: libroar/vio_pipe.c
===================================================================
--- libroar/vio_pipe.c	(revision 1301)
+++ libroar/vio_pipe.c	(revision 1304)
@@ -35,9 +35,9 @@
 #include "libroar.h"
 
-int roar_vio_open_pipe (struct roar_vio_calls * s1, struct roar_vio_calls * s2, int type, int flags) {
+int roar_vio_open_pipe (struct roar_vio_calls * s0, struct roar_vio_calls * s1, int type, int flags) {
  struct roar_vio_pipe * self;
  int                    rw = flags & (O_RDONLY|O_WRONLY|O_RDWR);
 
- if ( s1 == NULL || s2 == NULL )
+ if ( s0 == NULL || s1 == NULL )
   return -1;
 
@@ -48,5 +48,4 @@
 
  self->refcount = 2;
- self->type     = type;
  self->flags    = flags;
 
@@ -59,8 +58,12 @@
  }
 
+ self->type     = type;
+
  switch (type) {
   case ROAR_VIO_PIPE_TYPE_BUFFER:
     // no buffers need to be set up here,
     // we handle the NULL pointer in the reader and writer func
+    free(self);
+    return -1;
    break;
   case ROAR_VIO_PIPE_TYPE_PIPE:
@@ -97,5 +100,135 @@
  }
 
- return 0;
+ roar_vio_pipe_init(s0, self, flags);
+ roar_vio_pipe_init(s1, self, flags);
+
+ self->s0 = s0;
+
+ return 0;
+}
+
+int roar_vio_pipe_init (struct roar_vio_calls * s,  struct roar_vio_pipe * self, int flags) {
+ if ( s == NULL || self == NULL )
+  return -1;
+
+ memset(s, 0, sizeof(struct roar_vio_calls));
+
+ s->close    = roar_vio_pipe_close;
+ s->read     = roar_vio_pipe_read;
+ s->write    = roar_vio_pipe_write;
+ s->nonblock = roar_vio_pipe_nonblock;
+ s->sync     = roar_vio_pipe_sync;
+
+ s->inst = (void*) self;
+
+ if ( flags & O_NONBLOCK ) {
+  roar_vio_pipe_nonblock(s, ROAR_SOCKET_NONBLOCK);
+ }
+
+ return 0;
+}
+
+int     roar_vio_pipe_close   (struct roar_vio_calls * vio) {
+ struct roar_vio_pipe * self;
+ int                    idx;
+
+ if ( vio == NULL )
+  return -1;
+
+ if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL )
+  return -1;
+
+ self->refcount--;
+
+ switch (self->type) {
+  case ROAR_VIO_PIPE_TYPE_BUFFER:
+    // this will be a bit more complex as we need to change the flags, too.
+   break;
+  case ROAR_VIO_PIPE_TYPE_PIPE:
+   switch (ROAR_VIO_PIPE_S(self, vio)) {
+    case 0:
+      close(self->b.p[0]);
+      close(self->b.p[1]);
+      self->b.p[0] = -1;
+      self->b.p[1] = -1;
+     break;
+    case 1:
+      close(self->b.p[2]);
+      close(self->b.p[3]);
+      self->b.p[2] = -1;
+      self->b.p[3] = -1;
+     break;
+   }
+   break;
+  case ROAR_VIO_PIPE_TYPE_SOCKET:
+    close(self->b.p[idx = ROAR_VIO_PIPE_S(self, vio)]);
+    self->b.p[idx] = -1;
+   break;
+ }
+
+ if ( ! self->refcount ) {
+  free(self);
+ }
+
+ vio->inst = NULL;
+ return 0;
+}
+
+int     roar_vio_pipe_nonblock(struct roar_vio_calls * vio, int state) {
+ return -1;
+}
+
+int     roar_vio_pipe_sync    (struct roar_vio_calls * vio) {
+ // we may add fdatasync() calls here depending on the type
+ // but in general they should not be needed on pipes.
+ return 0;
+}
+
+ssize_t roar_vio_pipe_read    (struct roar_vio_calls * vio, void *buf, size_t count) {
+ struct roar_vio_pipe * self;
+
+ if ( vio == NULL )
+  return -1;
+
+ if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL )
+  return -1;
+
+ switch (self->type) {
+  case ROAR_VIO_PIPE_TYPE_BUFFER:
+    // this will be a bit more complex as we need to check the flags, too.
+   break;
+  case ROAR_VIO_PIPE_TYPE_PIPE:
+    return read(self->b.p[ROAR_VIO_PIPE_S(self,vio)*2], buf, count);
+   break;
+  case ROAR_VIO_PIPE_TYPE_SOCKET:
+    return read(self->b.p[ROAR_VIO_PIPE_S(self,vio)], buf, count);
+   break;
+ }
+
+ return -1;
+}
+
+ssize_t roar_vio_pipe_write   (struct roar_vio_calls * vio, void *buf, size_t count) {
+ struct roar_vio_pipe * self;
+
+ if ( vio == NULL )
+  return -1;
+
+ if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL )
+  return -1;
+
+ switch (self->type) {
+  case ROAR_VIO_PIPE_TYPE_BUFFER:
+    // this will be a bit more complex as we need to check the flags, too.
+   break;
+  case ROAR_VIO_PIPE_TYPE_PIPE:
+    return write(self->b.p[(ROAR_VIO_PIPE_S(self,vio)*2)+1], buf, count);
+   break;
+  case ROAR_VIO_PIPE_TYPE_SOCKET:
+    return write(self->b.p[ROAR_VIO_PIPE_S(self,vio)], buf, count);
+   break;
+ }
+
+ return -1;
 }
 
Index: roarclients/Makefile
===================================================================
--- roarclients/Makefile	(revision 1279)
+++ roarclients/Makefile	(revision 1304)
@@ -1,3 +1,3 @@
-TARGETS=roarcat roarcatad roarcat2sock roarcatsendfile roarcatplay roarcatpassfh roarbidir roarctl roarmon roarsockconnect roartypes roarvorbis roarvumeter roarfilt roarsin roar-config polytest roarsocktypes roarshout roarradio roarfctest roarmonhttp pinentrytest zcattest pgptest roarcatvio
+TARGETS=roarcat roarcatad roarcat2sock roarcatsendfile roarcatplay roarcatpassfh roarbidir roarctl roarmon roarsockconnect roartypes roarvorbis roarvumeter roarfilt roarsin roar-config polytest roarsocktypes roarshout roarradio roarfctest roarmonhttp pinentrytest zcattest pgptest roarcatvio pipetest
 
 include ../Makefile.conf
@@ -44,4 +44,5 @@
 zcattest: zcattest.o
 pgptest: pgptest.o
+pipetest: pipetest.o
 roarfctest: roarfctest.o
 	${CC} ${LDFLAGS} -o roarfctest roarfctest.o $(lib_m) -lroardsp
Index: roarclients/pipetest.c
===================================================================
--- roarclients/pipetest.c	(revision 1304)
+++ roarclients/pipetest.c	(revision 1304)
@@ -0,0 +1,62 @@
+//pipetest.c:
+
+/*
+ *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
+ *
+ *  This file is part of roarclients a part of RoarAudio,
+ *  a cross-platform sound system for both, home and professional use.
+ *  See README for details.
+ *
+ *  This file is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3
+ *  as published by the Free Software Foundation.
+ *
+ *  RoarAudio 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 software; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <roaraudio.h>
+
+#define BUF_MAX 1024
+
+int main (void) {
+ char buf[BUF_MAX];
+ size_t len;
+ struct roar_vio_calls s0, s1;
+ struct roar_vio_calls * me;
+
+ if ( roar_vio_open_pipe(&s0, &s1, ROAR_VIO_PIPE_TYPE_AUTO, O_RDWR) == -1 ) {
+  fprintf(stderr, "Error: can not create pipe\n");
+ }
+
+ switch (fork()) {
+  case 0:
+    me = &s0;
+    roar_vio_close(&s1);
+   break;
+  default:
+    me = &s1;
+    roar_vio_close(&s0);
+ }
+
+ snprintf(buf, BUF_MAX, "Hello from pid %i\n", getpid());
+ roar_vio_write(me, buf, strlen(buf));
+
+ buf[0] = 0;
+
+ roar_vio_read(me, buf, BUF_MAX);
+ printf("This is pid %i: %s", getpid(), buf);
+
+ roar_vio_close(me);
+
+ return 0;
+}
+
+//ll
