Index: tests/test_gicon.py
===================================================================
--- tests/test_gicon.py	(revision 948)
+++ tests/test_gicon.py	(working copy)
@@ -45,7 +45,7 @@
         stream, type = self.icon.load()
         try:
             self.assert_(isinstance(stream, gio.InputStream))
-            self.assertEquals(self.svg, stream.read())
+            self.assertEquals(self.svg, stream.read_all())
         finally:
             stream.close()
 
@@ -54,7 +54,7 @@
             try:
                 stream, type = icon.load_finish(result)
                 self.assert_(isinstance(stream, gio.InputStream))
-                self.assertEquals(self.svg, stream.read())
+                self.assertEquals(self.svg, stream.read_all())
             finally:
                 loop.quit()
                 stream.close()
Index: tests/test_gio.py
===================================================================
--- tests/test_gio.py	(revision 948)
+++ tests/test_gio.py	(working copy)
@@ -24,7 +24,7 @@
             try:
                 stream = file.read_finish(result)
                 self.failUnless(isinstance(stream, gio.InputStream))
-                self.assertEquals(stream.read(), "testing")
+                self.assertEquals(stream.read_all(), "testing")
             finally:
                 loop.quit()
 
@@ -482,9 +482,17 @@
         self._f.close()
         os.unlink("inputstream.txt")
 
-    def testRead(self):
-        self.assertEquals(self.stream.read(), "testing")
+    def testReadAll(self):
+        self.assertEquals(self.stream.read_all(), "testing")
 
+        self.stream = gio.MemoryInputStream()
+        self.assertEquals(self.stream.read_all(), '')
+
+        self.stream = gio.MemoryInputStream()
+        some_data = open("test_gio.py", "rb").read()
+        self.stream.add_data(some_data)
+        self.assertEquals(self.stream.read_all(), some_data)
+
     def testReadAsync(self):
         def callback(stream, result):
             self.assertEquals(result.get_op_res_gssize(), 7)
@@ -572,12 +580,12 @@
 
     def test_add_data(self):
         self.stream.add_data('foobar')
-        self.assertEquals('foobar', self.stream.read())
+        self.assertEquals('foobar', self.stream.read_all())
 
         self.stream.add_data('ham ')
         self.stream.add_data(None)
         self.stream.add_data('spam')
-        self.assertEquals('ham spam', self.stream.read())
+        self.assertEquals('ham spam', self.stream.read_all())
 
 
 class TestOutputStream(unittest.TestCase):
Index: gio/gio.override
===================================================================
--- gio/gio.override	(revision 948)
+++ gio/gio.override	(working copy)
@@ -105,7 +105,6 @@
   g_file_new_from_path
   g_file_new_from_uri
   g_file_hash
-  g_input_stream_read_all
   g_io_error_quark
   g_simple_async_result_new_error
   g_simple_async_report_error_in_idle
Index: gio/ginputstream.override
===================================================================
--- gio/ginputstream.override	(revision 948)
+++ gio/ginputstream.override	(working copy)
@@ -111,31 +111,32 @@
                                             &error);
             pyg_end_allow_threads;
 
-            if (pyg_error_check(&error))
-                {
-                    Py_DECREF(v);
-                    return NULL;
-                }
-            else if (chunksize == 0)
-                {
-                    PyErr_SetFromErrno(PyExc_IOError);
-                    Py_DECREF(v);
-                    return NULL;
-                }
+            if (pyg_error_check(&error)) {
+		Py_DECREF(v);
+		return NULL;
+	    }
+	    if (chunksize == 0) {
+		/* End of file. */
+                break;
+	    }
 
             bytesread += chunksize;
-            if (bytesread < buffersize)
+            if (bytesread < buffersize) {
+		/* g_input_stream_read() decided to not read full buffer.  We
+		 * then return early too, even if 'count' is less than 0.
+		 */
                 break;
+	    }
 
-            if (count < 0)
-                {
-                    buffersize += BUFSIZE;
-                    if (_PyString_Resize(&v, buffersize) < 0)
-                        return NULL;
-                }
-            else
+            if (count < 0) {
+		buffersize += BUFSIZE;
+		if (_PyString_Resize(&v, buffersize) < 0)
+		    return NULL;
+	    }
+            else {
                 /* Got what was requested. */
                 break;
+	    }
         }
 
     if (bytesread != buffersize)
@@ -144,6 +145,73 @@
     return v;
 }
 %%
+override g_input_stream_read_all kwargs
+static PyObject *
+_wrap_g_input_stream_read_all(PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = { "count", "cancellable", NULL };
+    PyGObject *pycancellable = NULL;
+    PyObject *v;
+    GCancellable *cancellable;
+    long count = -1;
+    GError *error = NULL;
+    size_t bytesread, buffersize, chunksize;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "|lO:InputStream.read",
+                                     kwlist, &count,
+                                     &pycancellable))
+        return NULL;
+
+    buffersize = BUFSIZE;
+
+    if (!pygio_check_cancellable(pycancellable, &cancellable))
+        return NULL;
+
+    v = PyString_FromStringAndSize((char *)NULL, buffersize);
+    if (v == NULL)
+        return NULL;
+
+    bytesread = 0;
+    for (;;)
+        {
+            pyg_begin_allow_threads;
+            errno = 0;
+            g_input_stream_read_all(G_INPUT_STREAM(self->obj),
+				    PyString_AS_STRING((PyStringObject *)v) + bytesread,
+				    buffersize - bytesread,
+				    &chunksize,
+				    cancellable, &error);
+            pyg_end_allow_threads;
+
+            if (pyg_error_check(&error)) {
+		Py_DECREF(v);
+		return NULL;
+	    }
+
+            bytesread += chunksize;
+            if (bytesread < buffersize || chunksize == 0) {
+		/* End of file. */
+                break;
+	    }
+
+            if (count < 0) {
+		buffersize += BUFSIZE;
+		if (_PyString_Resize(&v, buffersize) < 0)
+		    return NULL;
+	    }
+            else {
+                /* Got what was requested. */
+                break;
+	    }
+        }
+
+    if (bytesread != buffersize)
+        _PyString_Resize(&v, bytesread);
+
+    return v;
+}
+%%
 override g_input_stream_read_async kwargs
 static PyObject *
 _wrap_g_input_stream_read_async(PyGObject *self,
@@ -384,5 +452,4 @@
     Py_INCREF(Py_None);
     return Py_None;
 }
-/* GInputStream.read_all: No ArgType for void* */
 /* GInputStream.skip_async: No ArgType for GAsyncReadyCallback */
