$NetBSD: $

--- libxutil/file_stream.c.orig	2005-09-13 17:02:16.000000000 -0400
+++ libxutil/file_stream.c	2005-09-13 17:31:39.000000000 -0400
@@ -21,11 +21,13 @@
  */
 #ifndef __KERNEL__
 #include <stdio.h>
+#include <unistd.h>
 #include <stdlib.h>
 #include "allocate.h"
 #include "file_stream.h"
 
 static int file_read(IOStream *s, void *buf, size_t n);
+static int file_read_nbuf(IOStream *s, void* buf, size_t n);
 static int file_write(IOStream *s, const void *buf, size_t n);
 static int file_error(IOStream *s);
 static int file_close(IOStream *s);
@@ -42,6 +44,16 @@
     flush: file_flush,
 };
 
+/** Methods used by a FILE* IOStream that's unbuffered. */
+static const IOMethods file_methods_nbuf = {
+    read:  file_read_nbuf,
+    write: file_write,
+    error: file_error,
+    close: file_close,
+    free:  file_free,
+    flush: file_flush,
+};
+
 /** IOStream for stdin. */
 static IOStream _iostdin = {
     methods: &file_methods,
@@ -102,6 +114,7 @@
  * @return 0 on success, non-zero otherwise
  */
 int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){
+    io->methods = (mode == _IONBF) ? &file_methods_nbuf : &file_methods;
     return setvbuf(get_file(io), buf, mode, size);
 }
 
@@ -126,6 +139,15 @@
 static int file_read(IOStream *s, void *buf, size_t n){
     return fread(buf, 1, n, get_file(s));
 }
+static int file_read_nbuf(IOStream *s, void *buf, size_t n){
+    int fd = fileno(get_file(s)), rv, nr=0;
+    while(n > nr) {
+        rv = read(fd, buf+nr, n-nr);
+	if (rv <= 0) break;
+	nr += rv;
+    }
+    return nr;
+}
 
 /** Fush the underlying stream using fflush().
  *
