Index: include/libroar/vio.h
===================================================================
--- include/libroar/vio.h	(revision 1351)
+++ include/libroar/vio.h	(revision 1505)
@@ -49,4 +49,13 @@
  *   0x1XXX -> Server 
  */
+
+// basic calls:
+#define ROAR_VIO_CTL_GET_NEXT          0x0101
+#define ROAR_VIO_CTL_SET_NEXT          0x0102
+#define ROAR_VIO_CTL_GET_FH            0x0110
+#define ROAR_VIO_CTL_GET_READ_FH       0x0111
+#define ROAR_VIO_CTL_GET_WRITE_FH      0x0112
+#define ROAR_VIO_CTL_SELECT            0x0120
+
 // stream:
 #define ROAR_VIO_CTL_SET_STREAM    0x00010001 /* normal streams */
@@ -140,4 +149,5 @@
 int     roar_vio_basic_nonblock(struct roar_vio_calls * vio, int state);
 int     roar_vio_basic_sync    (struct roar_vio_calls * vio);
+int     roar_vio_basic_ctl     (struct roar_vio_calls * vio, int cmd, void * data);
 int     roar_vio_basic_close   (struct roar_vio_calls * vio);
 
@@ -169,4 +179,5 @@
 off_t   roar_vio_stdio_lseek   (struct roar_vio_calls * vio, off_t offset, int whence);
 int     roar_vio_stdio_sync    (struct roar_vio_calls * vio);
+int     roar_vio_stdio_ctl     (struct roar_vio_calls * vio, int cmd, void * data);
 int     roar_vio_stdio_close   (struct roar_vio_calls * vio);
 
Index: include/libroar/vio_pipe.h
===================================================================
--- include/libroar/vio_pipe.h	(revision 1310)
+++ include/libroar/vio_pipe.h	(revision 1505)
@@ -68,4 +68,5 @@
 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_ctl     (struct roar_vio_calls * vio, int cmd, void * data);
 int     roar_vio_pipe_close   (struct roar_vio_calls * vio);
 
Index: include/libroar/vio_stack.h
===================================================================
--- include/libroar/vio_stack.h	(revision 1327)
+++ include/libroar/vio_stack.h	(revision 1505)
@@ -56,4 +56,5 @@
 int     roar_vio_stack_nonblock(struct roar_vio_calls * vio, int state);
 int     roar_vio_stack_sync    (struct roar_vio_calls * vio);
+int     roar_vio_stack_ctl     (struct roar_vio_calls * vio, int cmd, void * data);
 int     roar_vio_stack_close   (struct roar_vio_calls * vio);
 
Index: libroar/vio.c
===================================================================
--- libroar/vio.c	(revision 1474)
+++ libroar/vio.c	(revision 1505)
@@ -57,4 +57,5 @@
  calls->nonblock = roar_vio_basic_nonblock;
  calls->sync     = roar_vio_basic_sync;
+ calls->ctl      = roar_vio_basic_ctl;
  calls->close    = roar_vio_basic_close;
 
@@ -380,4 +381,21 @@
  return 0;
 #endif
+}
+
+int     roar_vio_basic_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
+
+ if ( vio == NULL || cmd == -1 )
+  return -1;
+
+ switch (cmd) {
+  case ROAR_VIO_CTL_GET_FH:
+  case ROAR_VIO_CTL_GET_READ_FH:
+  case ROAR_VIO_CTL_GET_WRITE_FH:
+    *(int*)data = roar_vio_get_fh(vio);
+    return 0;
+   break;
+ }
+
+ return -1;
 }
 
@@ -441,4 +459,18 @@
 
 int     roar_vio_pass_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
+ if (vio == NULL || cmd == -1)
+  return -1;
+
+ switch (cmd) {
+  case ROAR_VIO_CTL_GET_NEXT:
+    *(struct roar_vio_calls **)data = vio->inst;
+    return 0;
+   break;
+  case ROAR_VIO_CTL_SET_NEXT:
+    vio->inst = *(struct roar_vio_calls **)data;
+    return 0;
+   break;
+ }
+
  return roar_vio_ctl((struct roar_vio_calls *) vio->inst, cmd, data);
 }
@@ -538,4 +570,21 @@
 }
 
+int     roar_vio_stdio_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
+
+ if ( vio == NULL || cmd == -1 )
+  return -1;
+
+ switch (cmd) {
+  case ROAR_VIO_CTL_GET_FH:
+  case ROAR_VIO_CTL_GET_READ_FH:
+  case ROAR_VIO_CTL_GET_WRITE_FH:
+   *(int*)data = fileno((FILE*)(vio->inst));
+    return 0;
+   break;
+ }
+
+ return -1;
+}
+
 int     roar_vio_stdio_close   (struct roar_vio_calls * vio) {
  return fclose((FILE*)(vio->inst));
Index: libroar/vio_pipe.c
===================================================================
--- libroar/vio_pipe.c	(revision 1470)
+++ libroar/vio_pipe.c	(revision 1505)
@@ -211,4 +211,51 @@
 }
 
+int     roar_vio_pipe_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
+ struct roar_vio_pipe * self;
+
+ if (vio == NULL || cmd == -1)
+  return -1;
+
+ if ( (self = (struct roar_vio_pipe *)vio->inst) == NULL )
+  return -1;
+
+ switch (cmd) {
+  case ROAR_VIO_CTL_GET_FH:
+    if ( self->type == ROAR_VIO_PIPE_TYPE_SOCKET ) {
+     *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)];
+     return 0;
+    } else {
+     return -1;
+    }
+   break;
+  case ROAR_VIO_CTL_GET_READ_FH:
+    switch (self->type) {
+     case ROAR_VIO_PIPE_TYPE_SOCKET:
+       *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)];
+       return 0;
+      break;
+     case ROAR_VIO_PIPE_TYPE_PIPE:
+       *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)*2];
+       return 0;
+      break;
+    }
+  case ROAR_VIO_CTL_GET_WRITE_FH:
+    switch (self->type) {
+     case ROAR_VIO_PIPE_TYPE_SOCKET:
+       *(int*)data = self->b.p[ROAR_VIO_PIPE_S(self,vio)];
+       return 0;
+      break;
+     case ROAR_VIO_PIPE_TYPE_PIPE:
+       *(int*)data = self->b.p[(ROAR_VIO_PIPE_SR(self,vio)*2)+1];
+       return 0;
+      break;
+    }
+   break;
+ }
+
+ return -1;
+}
+
+
 ssize_t roar_vio_pipe_read    (struct roar_vio_calls * vio, void *buf, size_t count) {
  struct roar_vio_pipe * self;
Index: libroar/vio_stack.c
===================================================================
--- libroar/vio_stack.c	(revision 1327)
+++ libroar/vio_stack.c	(revision 1505)
@@ -49,4 +49,5 @@
  calls->inst     = self;
  calls->close    = roar_vio_stack_close;
+ calls->ctl      = roar_vio_stack_ctl;
  calls->read     = roar_vio_stack_read;
  calls->write    = roar_vio_stack_write;
@@ -97,4 +98,21 @@
  return 0;
 }
+
+int     roar_vio_stack_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
+ if (vio == NULL || cmd == -1)
+  return -1;
+
+ switch (cmd) {
+  case ROAR_VIO_CTL_GET_FH:
+  case ROAR_VIO_CTL_GET_READ_FH:
+  case ROAR_VIO_CTL_GET_WRITE_FH:
+  case ROAR_VIO_CTL_SELECT:
+    return roar_vio_ctl(((struct roar_vio_stack*)(vio->inst))->cur, cmd, data);
+   break;
+ }
+
+ return -1;
+}
+
 
 ssize_t roar_vio_stack_read    (struct roar_vio_calls * vio, void *buf, size_t count) {
