Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
+++ uspace/lib/c/generic/io/io.c	(revision 587478b2be4192b088f4a64c8fde7adeec10d4eb)
@@ -53,4 +53,27 @@
 static void _fflushbuf(FILE *stream);
 
+static size_t stdio_kio_read(void *, size_t, size_t, FILE *);
+static size_t stdio_kio_write(const void *, size_t, size_t, FILE *);
+static int stdio_kio_flush(FILE *);
+
+static size_t stdio_vfs_read(void *, size_t, size_t, FILE *);
+static size_t stdio_vfs_write(const void *, size_t, size_t, FILE *);
+
+static int stdio_vfs_flush(FILE *);
+
+/** KIO stream ops */
+static __stream_ops_t stdio_kio_ops = {
+	.read = stdio_kio_read,
+	.write = stdio_kio_write,
+	.flush = stdio_kio_flush
+};
+
+/** VFS stream ops */
+static __stream_ops_t stdio_vfs_ops = {
+	.read = stdio_vfs_read,
+	.write = stdio_vfs_write,
+	.flush = stdio_vfs_flush
+};
+
 static FILE stdin_null = {
 	.fd = -1,
@@ -58,5 +81,6 @@
 	.error = true,
 	.eof = true,
-	.kio = false,
+	.ops = &stdio_vfs_ops,
+	.arg = NULL,
 	.sess = NULL,
 	.btype = _IONBF,
@@ -73,5 +97,6 @@
 	.error = false,
 	.eof = false,
-	.kio = true,
+	.ops = &stdio_kio_ops,
+	.arg = NULL,
 	.sess = NULL,
 	.btype = _IOLBF,
@@ -88,5 +113,6 @@
 	.error = false,
 	.eof = false,
-	.kio = true,
+	.ops = &stdio_kio_ops,
+	.arg = NULL,
 	.sess = NULL,
 	.btype = _IONBF,
@@ -328,5 +354,6 @@
 	stream->error = false;
 	stream->eof = false;
-	stream->kio = false;
+	stream->ops = &stdio_vfs_ops;
+	stream->arg = NULL;
 	stream->sess = NULL;
 	stream->need_sync = false;
@@ -352,5 +379,6 @@
 	stream->error = false;
 	stream->eof = false;
-	stream->kio = false;
+	stream->ops = &stdio_vfs_ops;
+	stream->arg = NULL;
 	stream->sess = NULL;
 	stream->need_sync = false;
@@ -435,19 +463,5 @@
 static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)
 {
-	errno_t rc;
-	size_t nread;
-
-	if (size == 0 || nmemb == 0)
-		return 0;
-
-	rc = vfs_read(stream->fd, &stream->pos, buf, size * nmemb, &nread);
-	if (rc != EOK) {
-		errno = rc;
-		stream->error = true;
-	} else if (nread == 0) {
-		stream->eof = true;
-	}
-
-	return (nread / size);
+	return stream->ops->read(buf, size, nmemb, stream);
 }
 
@@ -464,5 +478,4 @@
 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
 {
-	errno_t rc;
 	size_t nwritten;
 
@@ -470,18 +483,5 @@
 		return 0;
 
-	if (stream->kio) {
-		rc = kio_write(buf, size * nmemb, &nwritten);
-		if (rc != EOK) {
-			stream->error = true;
-			nwritten = 0;
-		}
-	} else {
-		rc = vfs_write(stream->fd, &stream->pos, buf, size * nmemb,
-		    &nwritten);
-		if (rc != EOK) {
-			errno = rc;
-			stream->error = true;
-		}
-	}
+	nwritten = stream->ops->write(buf, size, nmemb, stream);
 
 	if (nwritten > 0)
@@ -905,24 +905,13 @@
 	}
 
-	if (stream->kio) {
-		kio_update();
-		return 0;
-	}
-
-	if ((stream->fd >= 0) && (stream->need_sync)) {
-		errno_t rc;
-
+	if (stream->need_sync) {
 		/**
 		 * Better than syncing always, but probably still not the
 		 * right thing to do.
 		 */
+		if (stream->ops->flush(stream) == EOF)
+			return EOF;
+
 		stream->need_sync = false;
-		rc = vfs_sync(stream->fd);
-		if (rc != EOK) {
-			errno = rc;
-			return EOF;
-		}
-
-		return 0;
 	}
 
@@ -948,5 +937,5 @@
 int fileno(FILE *stream)
 {
-	if (stream->kio) {
+	if (stream->ops != &stdio_vfs_ops) {
 		errno = EBADF;
 		return EOF;
@@ -978,4 +967,84 @@
 }
 
+/** Read from KIO stream. */
+static size_t stdio_kio_read(void *buf, size_t size, size_t nmemb, FILE *stream)
+{
+	stream->eof = true;
+	return 0;
+}
+
+/** Write to KIO stream. */
+static size_t stdio_kio_write(const void *buf, size_t size, size_t nmemb,
+    FILE *stream)
+{
+	errno_t rc;
+	size_t nwritten;
+
+	rc = kio_write(buf, size * nmemb, &nwritten);
+	if (rc != EOK) {
+		stream->error = true;
+		nwritten = 0;
+	}
+
+	return nwritten / size;
+}
+
+/** Flush KIO stream. */
+static int stdio_kio_flush(FILE *stream)
+{
+	kio_update();
+	return 0;
+}
+
+/** Read from VFS stream. */
+static size_t stdio_vfs_read(void *buf, size_t size, size_t nmemb, FILE *stream)
+{
+	errno_t rc;
+	size_t nread;
+
+	if (size == 0 || nmemb == 0)
+		return 0;
+
+	rc = vfs_read(stream->fd, &stream->pos, buf, size * nmemb, &nread);
+	if (rc != EOK) {
+		errno = rc;
+		stream->error = true;
+	} else if (nread == 0) {
+		stream->eof = true;
+	}
+
+	return (nread / size);
+}
+
+/** Write to VFS stream. */
+static size_t stdio_vfs_write(const void *buf, size_t size, size_t nmemb,
+    FILE *stream)
+{
+	errno_t rc;
+	size_t nwritten;
+
+	rc = vfs_write(stream->fd, &stream->pos, buf, size * nmemb, &nwritten);
+	if (rc != EOK) {
+		errno = rc;
+		stream->error = true;
+	}
+
+	return nwritten / size;
+}
+
+/** Flush VFS stream. */
+static int stdio_vfs_flush(FILE *stream)
+{
+	errno_t rc;
+
+	rc = vfs_sync(stream->fd);
+	if (rc != EOK) {
+		errno = rc;
+		return EOF;
+	}
+
+	return 0;
+}
+
 /** @}
  */
