diff --git a/src/modules/Pipe/pipe.c b/src/modules/Pipe/pipe.c
index 0a380a3e9885d254a246b122ef59e9ca33516f93..8ef4aff54e94f4df64c1d86d3839154a998f6add 100644
--- a/src/modules/Pipe/pipe.c
+++ b/src/modules/Pipe/pipe.c
@@ -22,7 +22,7 @@
 #include <fcntl.h>
 
 #include "global.h"
-RCSID("$Id: pipe.c,v 1.15 1998/01/13 23:00:35 hubbe Exp $");
+RCSID("$Id: pipe.c,v 1.16 1998/04/03 19:58:15 grubba Exp $");
 
 #include "threads.h"
 #include "stralloc.h"
@@ -79,7 +79,7 @@ static struct program *pipe_program, *output_program;
 
 struct input
 {
-  enum { I_NONE,I_OBJ,I_STRING,I_MMAP } type;
+  enum { I_NONE,I_OBJ,I_BLOCKING_OBJ,I_STRING,I_MMAP } type;
   union
   {
     struct object *obj; 
@@ -188,6 +188,7 @@ static INLINE void free_input(struct input *i)
   switch (i->type)
   {
   case I_OBJ:
+  case I_BLOCKING_OBJ:
     if (!i->u.obj) break;
     if (i->u.obj->prog)
     {
@@ -337,6 +338,7 @@ static INLINE void input_finish(void)
 
   while(1)
   {
+    /* Get the next input from the queue */
     i=THIS->firstinput->next;
     free_input(THIS->firstinput);
     THIS->firstinput=i;
@@ -354,6 +356,22 @@ static INLINE void input_finish(void)
       pop_stack();
       return;
 
+    case I_BLOCKING_OBJ:
+      push_int(8192);
+      push_int(1);	/* We don't care if we don't get all 8192 bytes. */
+      apply(i->u.obj, "read", 2);
+      if (sp[-1].type == T_STRING) {
+	append_buffer(sp[-1].u.string);
+	pop_stack();
+	i->sleeping = 1;
+	return;
+      } else {
+	/* FIXME: Should we check the return value here? */
+	pop_stack();
+	/* EOF */
+	continue;
+      }
+
     case I_MMAP:
       if (THIS->fd==-1) return;
       continue;
@@ -428,12 +446,25 @@ static INLINE struct pike_string* gimme_some_data(unsigned long pos)
 	  this->firstinput &&
 	  this->bytes_in_buffer<MAX_BYTES_IN_BUFFER)
       {
-	this->sleeping=0;
-	push_callback(offset_input_read_callback);
-	push_int(0);
-	push_callback(offset_input_close_callback);
-	apply(this->firstinput->u.obj, "set_nonblocking", 3);
-	pop_stack();
+	if (this->type == I_BLOCKING_OBJ) {
+	  push_int(8192);
+	  push_int(1);	/* We don't care if we don't get all 8192 bytes. */
+	  apply(i->u.obj, "read", 2);
+	  if (sp[-1].type == T_STRING) {
+	    append_buffer(sp[-1].u.string);
+	  } else {
+	    this->sleeping = 0;
+	    /* We're not sleeping -- we're dead... */
+	  }
+	  pop_stack();
+	} else {
+	  this->sleeping=0;
+	  push_callback(offset_input_read_callback);
+	  push_int(0);
+	  push_callback(offset_input_close_callback);
+	  apply(this->firstinput->u.obj, "set_nonblocking", 3);
+	  pop_stack();
+	}
       }
    }
 
@@ -467,6 +498,7 @@ static INLINE struct pike_string* gimme_some_data(unsigned long pos)
 #endif
        if (this->firstinput->type!=I_OBJ)
        {
+	 /* FIXME: What about I_BLOCKING_OBJ? */
 	 input_finish();       /* shouldn't be anything else ... maybe a finished object */
        }
      }
@@ -681,14 +713,21 @@ static void pipe_input(INT32 args)
    if (i->set_nonblocking_offset<0 ||
        i->set_blocking_offset<0) 
    {
-      free_object(i->u.obj);
-      i->u.obj=NULL;
-      i->type=I_NONE;
-
-      nobjects--;
-      error("illegal file object%s%s\n",
-	    ((i->set_nonblocking_offset<0)?"; no set_nonblocking":""),
-	    ((i->set_blocking_offset<0)?"; no set_blocking":""));
+      if (find_identifier("read", i->u.obj->prog) < 0) {
+	 /* Not even a read function */
+	 free_object(i->u.obj);
+	 i->u.obj=NULL;
+	 i->type=I_NONE;
+
+	 nobjects--;
+	 error("illegal file object%s%s\n",
+	       ((i->set_nonblocking_offset<0)?"; no set_nonblocking":""),
+	       ((i->set_blocking_offset<0)?"; no set_blocking":""));
+      } else {
+	 /* Try blocking mode */
+	 i->type = I_BLOCKING_OBJ;
+	 return;
+      }
    }
   
    if (i==THIS->firstinput)