Index: uspace/lib/libc/generic/console.c
===================================================================
--- uspace/lib/libc/generic/console.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ 	(revision )
@@ -1,274 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2006 Jakub Vana
- * Copyright (c) 2008 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <libc.h>
-#include <async.h>
-#include <io/stream.h>
-#include <ipc/console.h>
-#include <ipc/services.h>
-#include <errno.h>
-#include <string.h>
-#include <console.h>
-
-static int console_phone = -1;
-
-/** Size of cbuffer. */
-#define CBUFFER_SIZE  256
-
-/** Buffer for writing characters to the console. */
-static char cbuffer[CBUFFER_SIZE];
-
-/** Pointer to end of cbuffer. */
-static char *cbuffer_end = cbuffer + CBUFFER_SIZE;
-
-/** Pointer to first available field in cbuffer. */
-static char *cbp = cbuffer;
-
-
-/** Write one character to the console via IPC. */
-static void cons_putchar(wchar_t c)
-{
-	console_wait();
-	async_msg_1(console_phone, CONSOLE_PUTCHAR, c);
-}
-
-/** Write characters to the console via IPC or to klog */
-static ssize_t cons_write(const char *buf, size_t size)
-{
-	console_open(false);
-	
-	if (console_phone >= 0) {
-		async_serialize_start();
-		
-		ipc_call_t answer;
-		aid_t req = async_send_0(console_phone, CONSOLE_WRITE, &answer);
-		ipcarg_t rc = ipc_data_write_start(console_phone, (void *) buf, size);
-		
-		if (rc != EOK) {
-			async_wait_for(req, NULL);
-			async_serialize_end();
-			return (ssize_t) rc;
-		}
-		
-		async_wait_for(req, &rc);
-		async_serialize_end();
-		
-		if (rc == EOK)
-			return (ssize_t) IPC_GET_ARG1(answer);
-		else
-			return -1;
-	} else
-		return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
-}
-
-/** Write all data from output buffer to the console. */
-static void cbuffer_flush(void)
-{
-	size_t len = cbp - cbuffer;
-	
-	while (len > 0) {
-		ssize_t rc = cons_write(cbuffer, cbp - cbuffer);
-		if (rc < 0)
-			return;
-		
-		len -= rc;
-	}
-	
-	cbp = cbuffer;
-}
-
-/** Drop all data in console output buffer. */
-static void cbuffer_drain(void)
-{
-	cbp = cbuffer;
-}
-
-/** Write one character to the output buffer. */
-static inline void cbuffer_putc(char c)
-{
-	if (cbp == cbuffer_end)
-		cbuffer_flush();
-	
-	*cbp++ = c;
-	
-	if (c == '\n')
-		cbuffer_flush();
-}
-
-int console_open(bool blocking)
-{
-	if (console_phone < 0) {
-		int phone;
-		
-		if (blocking)
-			phone = ipc_connect_me_to_blocking(PHONE_NS,
-			    SERVICE_CONSOLE, 0, 0);
-		else
-			phone = ipc_connect_me_to(PHONE_NS,
-			    SERVICE_CONSOLE, 0, 0);
-		
-		if (phone >= 0)
-			console_phone = phone;
-	}
-	
-	return console_phone;
-}
-
-void console_close(void)
-{
-	if (console_phone >= 0) {
-		if (ipc_hangup(console_phone) == 0)
-			console_phone = -1;
-	}
-}
-
-void console_wait(void)
-{
-	while (console_phone < 0)
-		console_open(true);
-}
-
-void console_clear(void)
-{
-	console_wait();
-	cbuffer_drain();
-	async_msg_0(console_phone, CONSOLE_CLEAR);
-}
-
-int console_get_size(int *rows, int *cols)
-{
-	console_wait();
-	
-	ipcarg_t r;
-	ipcarg_t c;
-	int rc = async_req_0_2(console_phone, CONSOLE_GETSIZE, &r, &c);
-	
-	*rows = (int) r;
-	*cols = (int) c;
-	
-	return rc;
-}
-
-void console_set_style(int style)
-{
-	console_wait();
-	cbuffer_flush();
-	async_msg_1(console_phone, CONSOLE_SET_STYLE, style);
-}
-
-void console_set_color(int fg_color, int bg_color, int flags)
-{
-	console_wait();
-	cbuffer_flush();
-	async_msg_3(console_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
-}
-
-void console_set_rgb_color(int fg_color, int bg_color)
-{
-	console_wait();
-	cbuffer_flush();
-	async_msg_2(console_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
-}
-
-void console_cursor_visibility(int show)
-{
-	console_wait();
-	cbuffer_flush();
-	async_msg_1(console_phone, CONSOLE_CURSOR_VISIBILITY, show != 0);
-}
-
-void console_kcon_enable(void)
-{
-	console_wait();
-	cbuffer_flush();
-	async_msg_0(console_phone, CONSOLE_KCON_ENABLE);
-}
-
-void console_goto(int row, int col)
-{
-	console_wait();
-	cbuffer_flush();
-	async_msg_2(console_phone, CONSOLE_GOTO, row, col);
-}
-
-void console_putchar(wchar_t c)
-{
-	console_wait();
-	cbuffer_flush();
-	cons_putchar(c);
-}
-
-/** Write characters to the console. */
-ssize_t console_write(const char *buf, size_t size)
-{
-	size_t left = size;
-	
-	while (left > 0) {
-		cbuffer_putc(*buf++);
-		left--;
-	}
-	
-	return size;
-}
-
-/** Write a NULL-terminated string to the console. */
-void console_putstr(const char *str)
-{
-	size_t left = str_size(str);
-	
-	while (left > 0) {
-		ssize_t rc = console_write(str, left);
-		
-		if (rc < 0) {
-			/* Error */
-			return;
-		}
-		
-		str += rc;
-		left -= rc;
-	}
-}
-
-/** Flush all output to the console or klog. */
-void console_flush(void)
-{
-	cbuffer_flush();
-	if (console_phone >= 0)
-		async_msg_0(console_phone, CONSOLE_FLUSH);
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/io/asprintf.c
===================================================================
--- uspace/lib/libc/generic/io/asprintf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/io/asprintf.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -37,40 +37,50 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <io/printf_core.h>
 
-static int asprintf_prewrite(const char *str, size_t count, void *unused)
+static int asprintf_str_write(const char *str, size_t count, void *unused)
 {
-	return count;
+	return str_nlength(str, count);
+}
+
+static int asprintf_wstr_write(const wchar_t *str, size_t count, void *unused)
+{
+	return wstr_nlength(str, count);
 }
 
 /** Allocate and print to string.
  *
- * @param strp		Address of the pointer where to store the address of
- * 			the newly allocated string.
- * @fmt			Format strin.
+ * @param strp Address of the pointer where to store the address of
+ *             the newly allocated string.
+ * @fmt        Format string.
  *
- * @return		Number of characters printed or a negative error code.
+ * @return Number of characters printed or a negative error code.
+ *
  */
 int asprintf(char **strp, const char *fmt, ...)
 {
 	struct printf_spec ps = {
-		 asprintf_prewrite,
-		 NULL
+		asprintf_str_write,
+		asprintf_wstr_write,
+		NULL
 	};
-	int ret;
+	
 	va_list args;
-
 	va_start(args, fmt);
-	ret = printf_core(fmt, &ps, args);
+	
+	int ret = printf_core(fmt, &ps, args);
 	va_end(args);
+	
 	if (ret > 0) {
-		*strp = malloc(ret + 20);
-		if (!*strp)
+		*strp = malloc(STR_BOUNDS(ret) + 1);
+		if (*strp == NULL)
 			return -1;
+		
 		va_start(args, fmt);
-		vsprintf(*strp, fmt, args);
-		va_end(args);		
+		vsnprintf(*strp, STR_BOUNDS(ret) + 1, fmt, args);
+		va_end(args);
 	}
-
+	
 	return ret;
 }
Index: uspace/lib/libc/generic/io/console.c
===================================================================
--- uspace/lib/libc/generic/io/console.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ uspace/lib/libc/generic/io/console.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2006 Jakub Vana
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <libc.h>
+#include <async.h>
+#include <io/console.h>
+#include <ipc/console.h>
+
+void console_clear(int phone)
+{
+	async_msg_0(phone, CONSOLE_CLEAR);
+}
+
+int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)
+{
+	return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols);
+}
+
+void console_set_style(int phone, int style)
+{
+	async_msg_1(phone, CONSOLE_SET_STYLE, style);
+}
+
+void console_set_color(int phone, int fg_color, int bg_color, int flags)
+{
+	async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
+}
+
+void console_set_rgb_color(int phone, int fg_color, int bg_color)
+{
+	async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
+}
+
+void console_cursor_visibility(int phone, bool show)
+{
+	async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
+}
+
+void console_kcon_enable(int phone)
+{
+	async_msg_0(phone, CONSOLE_KCON_ENABLE);
+}
+
+void console_goto(int phone, ipcarg_t row, ipcarg_t col)
+{
+	async_msg_2(phone, CONSOLE_GOTO, row, col);
+}
+
+bool console_get_event(int phone, console_event_t *event)
+{
+	ipcarg_t type;
+	ipcarg_t key;
+	ipcarg_t mods;
+	ipcarg_t c;
+	
+	int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
+	if (rc < 0)
+		return false;
+	
+	event->type = type;
+	event->key = key;
+	event->mods = mods;
+	event->c = c;
+	
+	return true;
+}
+
+/** @}
+ */
Index: uspace/lib/libc/generic/io/fprintf.c
===================================================================
--- uspace/lib/libc/generic/io/fprintf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ 	(revision )
@@ -1,77 +1,0 @@
-/*
- * Copyright (c) 2008 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/**
- * @file
- * @brief fprintf, vfprintf
- */ 
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <io/printf_core.h>
-
-static int vfprintf_str_write(const char *s, size_t size, void *f)
-{
-	/* FIXME: Should return number of characters? */
-	return fwrite(s, 1, size, (FILE *) f);
-}
-
-static int vfprintf_wstr_write(const char *s, size_t size, void *f)
-{
-	/* TODO */
-	return size;
-}
-
-int vfprintf(FILE *f, const char *fmt, va_list ap)
-{
-	struct printf_spec ps = {
-		vfprintf_str_write,
-		vfprintf_wstr_write,
-		(void *) f
-	};
-
-	return printf_core(fmt, &ps, ap);
-}
-
-int fprintf(FILE *f, const char *fmt, ...)
-{
-	int rv;
-	va_list args;
-
-	va_start(args, fmt);
-	rv = vfprintf(f, fmt, args);
-	va_end(args);
-
-	return rv;
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/io/io.c
===================================================================
--- uspace/lib/libc/generic/io/io.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/io/io.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -31,97 +31,338 @@
  */
 /** @file
- */ 
-
-#include <libc.h>
+ */
+
+#include <stdio.h>
 #include <unistd.h>
-#include <stdio.h>
-#include <io/io.h>
+#include <fcntl.h>
 #include <string.h>
 #include <errno.h>
-#include <console.h>
-
-const static char nl = '\n';
+#include <bool.h>
+#include <malloc.h>
+#include <io/klog.h>
+#include <vfs/vfs.h>
+#include <ipc/devmap.h>
+
+FILE stdin_null = {
+	.fd = -1,
+	.error = true,
+	.eof = true,
+	.klog = false,
+	.phone = -1
+};
+
+FILE stdout_klog = {
+	.fd = -1,
+	.error = false,
+	.eof = false,
+	.klog = true,
+	.phone = -1
+};
+
+FILE *stdin = &stdin_null;
+FILE *stdout = &stdout_klog;
+FILE *stderr = &stdout_klog;
+
+static bool parse_mode(const char *mode, int *flags)
+{
+	/* Parse mode except first character. */
+	const char *mp = mode;
+	if (*mp++ == 0) {
+		errno = EINVAL;
+		return false;
+	}
+	
+	if ((*mp == 'b') || (*mp == 't'))
+		mp++;
+	
+	bool plus;
+	if (*mp == '+') {
+		mp++;
+		plus = true;
+	} else
+		plus = false;
+	
+	if (*mp != 0) {
+		errno = EINVAL;
+		return false;
+	}
+	
+	/* Parse first character of mode and determine flags for open(). */
+	switch (mode[0]) {
+	case 'r':
+		*flags = plus ? O_RDWR : O_RDONLY;
+		break;
+	case 'w':
+		*flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
+		break;
+	case 'a':
+		/* TODO: a+ must read from beginning, append to the end. */
+		if (plus) {
+			errno = ENOTSUP;
+			return false;
+		}
+		*flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
+	default:
+		errno = EINVAL;
+		return false;
+	}
+	
+	return true;
+}
+
+/** Open a stream.
+ *
+ * @param path Path of the file to open.
+ * @param mode Mode string, (r|w|a)[b|t][+].
+ *
+ */
+FILE *fopen(const char *path, const char *mode)
+{
+	int flags;
+	if (!parse_mode(mode, &flags))
+		return NULL;
+	
+	/* Open file. */
+	FILE *stream = malloc(sizeof(FILE));
+	if (stream == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	stream->fd = open(path, flags, 0666);
+	if (stream->fd < 0) {
+		/* errno was set by open() */
+		free(stream);
+		return NULL;
+	}
+	
+	stream->error = false;
+	stream->eof = false;
+	stream->klog = false;
+	stream->phone = -1;
+	
+	return stream;
+}
+
+FILE *fopen_node(fs_node_t *node, const char *mode)
+{
+	int flags;
+	if (!parse_mode(mode, &flags))
+		return NULL;
+	
+	/* Open file. */
+	FILE *stream = malloc(sizeof(FILE));
+	if (stream == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	
+	stream->fd = open_node(node, flags);
+	if (stream->fd < 0) {
+		/* errno was set by open_node() */
+		free(stream);
+		return NULL;
+	}
+	
+	stream->error = false;
+	stream->eof = false;
+	stream->klog = false;
+	stream->phone = -1;
+	
+	return stream;
+}
+
+int fclose(FILE *stream)
+{
+	int rc = 0;
+	
+	fflush(stream);
+	
+	if (stream->phone >= 0)
+		ipc_hangup(stream->phone);
+	
+	if (stream->fd >= 0)
+		rc = close(stream->fd);
+	
+	if ((stream != &stdin_null) && (stream != &stdout_klog))
+		free(stream);
+	
+	stream = NULL;
+	
+	if (rc != 0) {
+		/* errno was set by close() */
+		return EOF;
+	}
+	
+	return 0;
+}
+
+/** Read from a stream.
+ *
+ * @param buf    Destination buffer.
+ * @param size   Size of each record.
+ * @param nmemb  Number of records to read.
+ * @param stream Pointer to the stream.
+ *
+ */
+size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
+{
+	size_t left = size * nmemb;
+	size_t done = 0;
+	
+	while ((left > 0) && (!stream->error) && (!stream->eof)) {
+		ssize_t rd = read(stream->fd, buf + done, left);
+		
+		if (rd < 0)
+			stream->error = true;
+		else if (rd == 0)
+			stream->eof = true;
+		else {
+			left -= rd;
+			done += rd;
+		}
+	}
+	
+	return (done / size);
+}
+
+/** Write to a stream.
+ *
+ * @param buf    Source buffer.
+ * @param size   Size of each record.
+ * @param nmemb  Number of records to write.
+ * @param stream Pointer to the stream.
+ *
+ */
+size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
+{
+	size_t left = size * nmemb;
+	size_t done = 0;
+	
+	while ((left > 0) && (!stream->error)) {
+		ssize_t wr;
+		
+		if (stream->klog)
+			wr = klog_write(buf + done, left);
+		else
+			wr = write(stream->fd, buf + done, left);
+		
+		if (wr <= 0)
+			stream->error = true;
+		else {
+			left -= wr;
+			done += wr;
+		}
+	}
+	
+	return (done / size);
+}
+
+int fputc(wchar_t c, FILE *stream)
+{
+	char buf[STR_BOUNDS(1)];
+	size_t sz = 0;
+	
+	if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) {
+		size_t wr = fwrite(buf, sz, 1, stream);
+		
+		if (wr < sz)
+			return EOF;
+		
+		return (int) c;
+	}
+	
+	return EOF;
+}
+
+int putchar(wchar_t c)
+{
+	return fputc(c, stdout);
+}
+
+int fputs(const char *str, FILE *stream)
+{
+	return fwrite(str, str_size(str), 1, stream);
+}
 
 int puts(const char *str)
 {
-	size_t count;
-	
-	if (str == NULL)
-		return putnchars("(NULL)", 6);
-	
-	for (count = 0; str[count] != 0; count++);
-	
-	if (console_write((void *) str, count) == count) {
-		if (console_write(&nl, 1) == 1)
-			return 0;
-	}
-	
-	return EOF;
-}
-
-/** Put count chars from buffer to stdout without adding newline
- * @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
- * @param count 
- * @return 0 on succes, EOF on fail
- */
-int putnchars(const char *buf, size_t count)
-{
-	if (console_write((void *) buf, count) == count)
-		return 0;
-	
-	return EOF;
-}
-
-/** Same as puts, but does not print newline at end
- *
- */
-int putstr(const char *str)
-{
-	size_t count;
-	
-	if (str == NULL)
-		return putnchars("(NULL)", 6);
-
-	for (count = 0; str[count] != 0; count++);
-	if (console_write((void *) str, count) == count)
-		return 0;
-	
-	return EOF;
-}
-
-int putchar(int c)
-{
-	char buf[STR_BOUNDS(1)];
-	size_t offs;
-
-	offs = 0;
-	if (chr_encode(c, buf, &offs, STR_BOUNDS(1)) != EOK)
+	return fputs(str, stdout);
+}
+
+int fgetc(FILE *stream)
+{
+	char c;
+	
+	if (fread(&c, sizeof(char), 1, stream) < sizeof(char))
 		return EOF;
-
-	if (console_write((void *) buf, offs) == offs)
-		return c;
-
-	return EOF;
+	
+	return (int) c;
 }
 
 int getchar(void)
 {
-	unsigned char c;
-	
-	console_flush();
-	if (read_stdin((void *) &c, 1) == 1)
-		return c;
-	
-	return EOF;
-}
-
-int fflush(FILE *f)
-{
-	/* Dummy implementation */
-	(void) f;
-	console_flush();
+	return fgetc(stdin);
+}
+
+int fseek(FILE *stream, long offset, int origin)
+{
+	off_t rc = lseek(stream->fd, offset, origin);
+	if (rc == (off_t) (-1)) {
+		/* errno has been set by lseek. */
+		return -1;
+	}
+	
+	stream->eof = false;
+	
 	return 0;
 }
 
+int fflush(FILE *stream)
+{
+	if (stream->klog) {
+		klog_update();
+		return EOK;
+	}
+	
+	if (stream->fd >= 0)
+		return fsync(stream->fd);
+	
+	return ENOENT;
+}
+
+int feof(FILE *stream)
+{
+	return stream->eof;
+}
+
+int ferror(FILE *stream)
+{
+	return stream->error;
+}
+
+int fphone(FILE *stream)
+{
+	if (stream->fd >= 0) {
+		if (stream->phone < 0)
+			stream->phone = fd_phone(stream->fd);
+		
+		return stream->phone;
+	}
+	
+	return -1;
+}
+
+void fnode(FILE *stream, fs_node_t *node)
+{
+	if (stream->fd >= 0) {
+		fd_node(stream->fd, node);
+	} else {
+		node->fs_handle = 0;
+		node->dev_handle = 0;
+		node->index = 0;
+	}
+}
+
 /** @}
  */
Index: uspace/lib/libc/generic/io/klog.c
===================================================================
--- uspace/lib/libc/generic/io/klog.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ uspace/lib/libc/generic/io/klog.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2006 Jakub Vana
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <libc.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <io/klog.h>
+
+size_t klog_write(const void *buf, size_t size)
+{
+	return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
+}
+
+void klog_update(void)
+{
+	(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/generic/io/printf.c
===================================================================
--- uspace/lib/libc/generic/io/printf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/io/printf.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -35,21 +35,41 @@
 #include <io/printf_core.h>
 #include <stdio.h>
-#include <stdio.h>
 
 /** Print formatted text.
- * @param fmt	format string
+ *
+ * @param stream Output stream
+ * @param fmt    Format string
+ *
  * \see For more details about format string see printf_core.
+ *
+ */
+int fprintf(FILE *stream, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	int ret = vfprintf(stream, fmt, args);
+	
+	va_end(args);
+	
+	return ret;
+}
+
+/** Print formatted text to stdout.
+ *
+ * @param fmt Format string
+ *
+ * \see For more details about format string see printf_core.
+ *
  */
 int printf(const char *fmt, ...)
 {
-	int ret;
 	va_list args;
-
 	va_start(args, fmt);
-
-	ret = vprintf(fmt, args);
+	
+	int ret = vprintf(fmt, args);
 	
 	va_end(args);
-
+	
 	return ret;
 }
Index: uspace/lib/libc/generic/io/printf_core.c
===================================================================
--- uspace/lib/libc/generic/io/printf_core.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/io/printf_core.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -174,5 +174,5 @@
 static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
 {
-	count_t counter = 0;
+	size_t counter = 0;
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
 		while (--width > 0) {
@@ -212,5 +212,5 @@
 static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
 {
-	count_t counter = 0;
+	size_t counter = 0;
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
 		while (--width > 0) {
@@ -255,10 +255,10 @@
 
 	/* Print leading spaces. */
-	count_t strw = str_length(str);
+	size_t strw = str_length(str);
 	if (precision == 0)
 		precision = strw;
 
 	/* Left padding */
-	count_t counter = 0;
+	size_t counter = 0;
 	width -= precision;
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
@@ -311,5 +311,5 @@
 	
 	/* Left padding */
-	count_t counter = 0;
+	size_t counter = 0;
 	width -= precision;
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
@@ -433,5 +433,5 @@
 	
 	width -= precision + size - number_size;
-	count_t counter = 0;
+	size_t counter = 0;
 	
 	if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
@@ -596,5 +596,5 @@
 	size_t j = 0;    /* Index to the first not printed nonformating character */
 	
-	count_t counter = 0;  /* Number of characters printed */
+	size_t counter = 0;   /* Number of characters printed */
 	int retval;           /* Return values from nested functions */
 	
Index: uspace/lib/libc/generic/io/snprintf.c
===================================================================
--- uspace/lib/libc/generic/io/snprintf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/io/snprintf.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -38,19 +38,21 @@
 
 /** Print formatted to the given buffer with limited size.
- * @param str	buffer
- * @param size	buffer size
- * @param fmt	format string
+ *
+ * @param str  Buffer
+ * @param size Buffer size
+ * @param fmt  Format string
+ *
  * \see For more details about format string see printf_core.
+ *
  */
 int snprintf(char *str, size_t size, const char *fmt, ...)
 {
-	int ret;
 	va_list args;
+	va_start(args, fmt);
 	
-	va_start(args, fmt);
-	ret = vsnprintf(str, size, fmt, args);
-
+	int ret = vsnprintf(str, size, fmt, args);
+	
 	va_end(args);
-
+	
 	return ret;
 }
Index: uspace/lib/libc/generic/io/sprintf.c
===================================================================
--- uspace/lib/libc/generic/io/sprintf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <io/printf_core.h>
-
-/** Print formatted to the given buffer.
- * @param str	buffer
- * @param fmt	format string
- * \see For more details about format string see printf_core.
- */
-int sprintf(char *str, const char *fmt, ...)
-{
-	int ret;
-	va_list args;
-	
-	va_start(args, fmt);
-	ret = vsprintf(str, fmt, args);
-	va_end(args);
-
-	return ret;
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/io/stdio.c
===================================================================
--- uspace/lib/libc/generic/io/stdio.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ 	(revision )
@@ -1,278 +1,0 @@
-/*
- * Copyright (c) 2008 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/**
- * @file
- * @brief ANSI C Stream I/O.
- */ 
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <bool.h>
-#include <stdio.h>
-
-FILE *stdin, *stdout, *stderr;
-
-/**
- * Open a stream.
- *
- * @param file_name	Name of the file to open.
- * @param mode		Mode string, (r|w|a)[b|t][+].
- */
-FILE *fopen(const char *file_name, const char *mode)
-{
-	FILE *f;
-	int flags;
-	bool plus;
-	const char *mp;
-
-	/* Parse mode except first character. */
-
-	mp = mode;
-	if (*mp++ == '\0') {
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if (*mp == 'b' || *mp == 't') ++mp;
-
-	if (*mp == '+') {
-		++mp;
-		plus = true;
-	} else {
-		plus = false;
-	}
-
-	if (*mp != '\0') {
-		errno = EINVAL;
-		return NULL;
-	}
-
-	/* Parse first character of mode and determine flags for open(). */
-
-	switch (mode[0]) {
-	case 'r':
-		flags = plus ? O_RDWR : O_RDONLY;
-		break;
-	case 'w':
-		flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
-		break;
-	case 'a':
-		/* TODO: a+ must read from beginning, append to the end. */
-		if (plus) {
-			errno = ENOTSUP;
-			return NULL;
-		}
-		flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
-	default:
-		errno = EINVAL;
-		return NULL;
-	}
-
-	/* Open file. */
-	
-	f = malloc(sizeof(FILE));
-	if (f == NULL) {
-		errno = ENOMEM;
-		return NULL;
-	}
-
-	f->fd = open(file_name, flags, 0666);
-	if (f->fd < 0) {
-		free(f);
-		return NULL; /* errno was set by open() */
-	}
-
-	f->error = 0;
-	f->eof = 0;
-
-	return f;
-}
-
-/** Close a stream.
- *
- * @param f	Pointer to stream.
- * @return	0 on success, EOF on error.
- */
-int fclose(FILE *f)
-{
-	int rc;
-
-	rc = close(f->fd);
-	free(f);
-
-	if (rc != 0)
-		return EOF; /* errno was set by close() */
-
-	return 0;
-}
-
-/** Read from a stream.
- *
- * @param buf	Destination buffer.
- * @param size	Size of each record.
- * @param nmemb Number of records to read.
- * @param f	Pointer to the stream.
- */
-size_t fread(void *buf, size_t size, size_t nmemb, FILE *f)
-{
-	size_t left, done, n;
-
-	left = size * nmemb;
-	done = 0;
-
-	while (left > 0 && !f->error && !f->eof) {
-		n = read(f->fd, buf + done, left);
-
-		if (n < 0) {
-			f->error = 1;
-		} else if (n == 0) {
-			f->eof = 1;
-		} else {
-			left -= n;
-			done += n;
-		}
-	}
-
-	return done / size;
-}
-
-
-/** Write to a stream.
- *
- * @param buf	Source buffer.
- * @param size	Size of each record.
- * @param nmemb Number of records to write.
- * @param f	Pointer to the stream.
- */
-size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *f)
-{
-	size_t left, done, n;
-
-	left = size * nmemb;
-	done = 0;
-
-	while (left > 0 && !f->error) {
-		n = write(f->fd, buf + done, left);
-
-		if (n <= 0) {
-			f->error = 1;
-		} else {
-			left -= n;
-			done += n;
-		}
-	} 
-
-	return done / size;
-}
-
-/** Return the end-of-file indicator of a stream. */
-int feof(FILE *f)
-{
-	return f->eof;
-}
-
-/** Return the error indicator of a stream. */
-int ferror(FILE *f)
-{
-	return f->error;
-}
-
-/** Clear the error and end-of-file indicators of a stream. */
-void clearerr(FILE *f)
-{
-	f->eof = 0;
-	f->error = 0;
-}
-
-/** Read character from a stream. */
-int fgetc(FILE *f)
-{
-	unsigned char c;
-	size_t n;
-
-	n = fread(&c, sizeof(c), 1, f);
-	if (n < 1) return EOF;
-
-	return (int) c;
-}
-
-/** Write character to a stream. */
-int fputc(int c, FILE *f)
-{
-	unsigned char cc;
-	size_t n;
-
-	cc = (unsigned char) c;
-	n = fwrite(&cc, sizeof(cc), 1, f);
-	if (n < 1) return EOF;
-
-	return (int) cc;
-}
-
-/** Write string to a stream. */
-int fputs(const char *s, FILE *f)
-{
-	int rc;
-
-	rc = 0;
-
-	while (*s && rc >= 0) {
-		rc = fputc(*s++, f);
-	}
-
-	if (rc < 0) return EOF;
-
-	return 0;
-}
-
-/** Seek to position in stream. */
-int fseek(FILE *f, long offset, int origin)
-{
-	off_t rc;
-
-	rc = lseek(f->fd, offset, origin);
-	if (rc == (off_t) (-1)) {
-		/* errno has been set by lseek. */
-		return -1;
-	}
-
-	f->eof = 0;
-
-	return 0;
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/io/stream.c
===================================================================
--- uspace/lib/libc/generic/io/stream.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ 	(revision )
@@ -1,86 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2006 Jakub Vana
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <io/io.h>
-#include <io/stream.h>
-#include <string.h>
-#include <malloc.h>
-#include <libc.h>
-#include <ipc/ipc.h>
-#include <ipc/ns.h>
-#include <ipc/fb.h>
-#include <ipc/services.h>
-#include <ipc/console.h>
-#include <console.h>
-#include <kbd/kbd.h>
-#include <unistd.h>
-#include <async.h>
-#include <sys/types.h>
-
-ssize_t read_stdin(void *buf, size_t count)
-{
-	int cons_phone = console_open(false);
-	
-	if (cons_phone >= 0) {
-		kbd_event_t ev;
-		int rc;
-		size_t i = 0;
-		
-		while (i < count) {
-			do {
-				rc = kbd_get_event(&ev);
-				if (rc < 0) return -1;
-			} while (ev.c == 0 || ev.type == KE_RELEASE);
-			
-			((char *) buf)[i++] = ev.c;
-		}
-		return i;
-	} else
-		return -1;
-}
-
-/** Write a string to klog. */
-int klog_puts(const char *str)
-{
-	return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) str, str_size(str));
-}
-
-void klog_update(void)
-{
-	(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/io/vprintf.c
===================================================================
--- uspace/lib/libc/generic/io/vprintf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/io/vprintf.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -39,35 +39,23 @@
 #include <futex.h>
 #include <async.h>
-#include <console.h>
+#include <string.h>
 
 static atomic_t printf_futex = FUTEX_INITIALIZER;
 
-static int vprintf_str_write(const char *str, size_t size, void *data)
+static int vprintf_str_write(const char *str, size_t size, void *stream)
+{
+	size_t wr = fwrite(str, 1, size, (FILE *) stream);
+	return str_nlength(str, wr);
+}
+
+static int vprintf_wstr_write(const wchar_t *str, size_t size, void *stream)
 {
 	size_t offset = 0;
-	size_t prev;
-	count_t chars = 0;
+	size_t chars = 0;
 	
 	while (offset < size) {
-		prev = offset;
-		str_decode(str, &offset, size);
-		console_write(str + prev, offset - prev);
-		chars++;
-	}
-	
-	return chars;
-}
-
-static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
-{
-	size_t offset = 0;
-	size_t boff;
-	count_t chars = 0;
-	char buf[4];
-	
-	while (offset < size) {
-		boff = 0;
-		chr_encode(str[chars], buf, &boff, 4);
-		console_write(buf, boff);
+		if (fputc(str[chars], (FILE *) stream) <= 0)
+			break;
+		
 		chars++;
 		offset += sizeof(wchar_t);
@@ -77,21 +65,26 @@
 }
 
-
 /** Print formatted text.
- * @param fmt	format string
- * @param ap	format parameters
+ *
+ * @param stream Output stream
+ * @param fmt    Format string
+ * @param ap     Format parameters
+ *
  * \see For more details about format string see printf_core.
+ *
  */
-int vprintf(const char *fmt, va_list ap)
+int vfprintf(FILE *stream, const char *fmt, va_list ap)
 {
 	struct printf_spec ps = {
 		vprintf_str_write,
 		vprintf_wstr_write,
-		 NULL
+		stream
 	};
+	
 	/*
 	 * Prevent other threads to execute printf_core()
 	 */
 	futex_down(&printf_futex);
+	
 	/*
 	 * Prevent other pseudo threads of the same thread
@@ -99,8 +92,25 @@
 	 */
 	async_serialize_start();
+	
 	int ret = printf_core(fmt, &ps, ap);
+	
 	async_serialize_end();
 	futex_up(&printf_futex);
+	
 	return ret;
+}
+
+/** Print formatted text to stdout.
+ *
+ * @param file Output stream
+ * @param fmt  Format string
+ * @param ap   Format parameters
+ *
+ * \see For more details about format string see printf_core.
+ *
+ */
+int vprintf(const char *fmt, va_list ap)
+{
+	return vfprintf(stdout, fmt, ap);
 }
 
Index: uspace/lib/libc/generic/io/vsnprintf.c
===================================================================
--- uspace/lib/libc/generic/io/vsnprintf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/io/vsnprintf.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -83,5 +83,5 @@
 		 * of string
 		 */
-		index_t index = 0;
+		size_t index = 0;
 		
 		while (index < size) {
@@ -131,5 +131,5 @@
 static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
 {
-	index_t index = 0;
+	size_t index = 0;
 	
 	while (index < (size / sizeof(wchar_t))) {
Index: uspace/lib/libc/generic/io/vsprintf.c
===================================================================
--- uspace/lib/libc/generic/io/vsprintf.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <io/printf_core.h>
-
-/** Print formatted to the given buffer.
- * @param str	buffer
- * @param fmt	format string
- * @param ap	argument list
- * \see For more details about format string see printf_core.
- */
-int vsprintf(char *str, const char *fmt, va_list ap)
-{
-	return vsnprintf(str, (size_t) - 1, fmt, ap);
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/kbd.c
===================================================================
--- uspace/lib/libc/generic/kbd.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */ 
-
-#include <stdio.h>
-#include <io/stream.h>
-#include <kbd/kbd.h>
-#include <ipc/ipc.h>
-#include <ipc/console.h>
-#include <console.h>
-#include <async.h>
-
-int kbd_get_event(kbd_event_t *ev)
-{
-	int cons_phone = console_open(true);
-	ipcarg_t r0, r1, r2, r3;
-	int rc;
-
-	rc = async_req_0_4(cons_phone, CONSOLE_GETKEY, &r0, &r1, &r2, &r3);
-	if (rc < 0)
-		return -1;
-
-	ev->type = r0;
-	ev->key = r1;
-	ev->mods = r2;
-	ev->c = r3;
-
-	return 0;
-}
-
-/** @}
- */
Index: uspace/lib/libc/generic/vfs/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs/vfs.c	(revision b78d0bd5a1809ce74a9c6476c8045976682e0eb0)
+++ uspace/lib/libc/generic/vfs/vfs.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
@@ -50,10 +50,11 @@
 #include <string.h>
 #include <devmap.h>
-#include "../../../srv/vfs/vfs.h"
-
-int vfs_phone = -1;
-futex_t vfs_phone_futex = FUTEX_INITIALIZER;
-
-futex_t cwd_futex = FUTEX_INITIALIZER;
+#include <ipc/vfs.h>
+#include <ipc/devmap.h>
+
+static int vfs_phone = -1;
+static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
+static futex_t cwd_futex = FUTEX_INITIALIZER;
+
 DIR *cwd_dir = NULL;
 char *cwd_path = NULL;
@@ -211,7 +212,8 @@
 	futex_up(&vfs_phone_futex);
 	free(pa);
-
+	
 	if (rc != EOK)
 	    return (int) rc;
+	
 	return (int) IPC_GET_ARG1(answer);
 }
@@ -220,4 +222,25 @@
 {
 	return _open(path, L_FILE, oflag);
+}
+
+int open_node(fs_node_t *node, int oflag)
+{
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
+	ipc_call_t answer;
+	aid_t req = async_send_4(vfs_phone, VFS_OPEN_NODE, node->fs_handle,
+	    node->dev_handle, node->index, oflag, &answer);
+	
+	ipcarg_t rc;
+	async_wait_for(req, &rc);
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
+	
+	if (rc != EOK)
+	    return (int) rc;
+	
+	return (int) IPC_GET_ARG1(answer);
 }
 
@@ -290,4 +313,62 @@
 	else
 		return -1;
+}
+
+int fd_phone(int fildes)
+{
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
+	ipcarg_t device;
+	ipcarg_t rc = async_req_1_1(vfs_phone, VFS_DEVICE, fildes, &device);
+	
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
+	
+	if (rc != EOK)
+		return -1;
+	
+	return devmap_device_connect((dev_handle_t) device, 0);
+}
+
+void fd_node(int fildes, fs_node_t *node)
+{
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
+	ipcarg_t fs_handle;
+	ipcarg_t dev_handle;
+	ipcarg_t index;
+	ipcarg_t rc = async_req_1_3(vfs_phone, VFS_NODE, fildes, &fs_handle,
+	    &dev_handle, &index);
+	
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
+	
+	if (rc == EOK) {
+		node->fs_handle = (fs_handle_t) fs_handle;
+		node->dev_handle = (dev_handle_t) dev_handle;
+		node->index = (fs_index_t) index;
+	} else {
+		node->fs_handle = 0;
+		node->dev_handle = 0;
+		node->index = 0;
+	}
+}
+
+int fsync(int fildes)
+{
+	futex_down(&vfs_phone_futex);
+	async_serialize_start();
+	vfs_connect();
+	
+	ipcarg_t rc = async_req_1_0(vfs_phone, VFS_SYNC, fildes);
+	
+	async_serialize_end();
+	futex_up(&vfs_phone_futex);
+	
+	return (int) rc;
 }
 
@@ -387,5 +468,5 @@
 	futex_up(&vfs_phone_futex);
 	free(pa);
-	return rc; 
+	return rc;
 }
 
@@ -417,5 +498,5 @@
 	futex_up(&vfs_phone_futex);
 	free(pa);
-	return rc; 
+	return rc;
 }
 
