Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -160,5 +160,5 @@
 		printf("%6u  ", lineno);
 	}
-	putchar(c);
+	putwchar(c);
 	last_char_was_newline = c == '\n';
 	if (paging_enabled) {
Index: uspace/app/bdsh/cmds/modules/printf/printf.c
===================================================================
--- uspace/app/bdsh/cmds/modules/printf/printf.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/app/bdsh/cmds/modules/printf/printf.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -172,9 +172,9 @@
 				break;
 			}
-			putchar(ch);
+			putwchar(ch);
 			break;
 
 		emit:
-			putchar(ch);
+			putwchar(ch);
 			esc_flag = false;
 		}
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/app/edit/edit.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -671,5 +671,5 @@
 				default:
 					if (kev->c >= 32 && nc < max_len) {
-						putchar(kev->c);
+						putwchar(kev->c);
 						console_flush(con);
 						buffer[nc++] = kev->c;
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/app/kio/kio.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -122,9 +122,9 @@
 
 		for (size_t i = 0; i < item->length; i++)
-			putchar(item->data[i]);
+			putwchar(item->data[i]);
 
 		if (log != NULL) {
 			for (size_t i = 0; i < item->length; i++)
-				fputc(item->data[i], log);
+				fputwc(item->data[i], log);
 
 			fflush(log);
Index: uspace/dist/src/c/demos/edit/edit.c
===================================================================
--- uspace/dist/src/c/demos/edit/edit.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/dist/src/c/demos/edit/edit.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -671,5 +671,5 @@
 				default:
 					if (kev->c >= 32 && nc < max_len) {
-						putchar(kev->c);
+						putwchar(kev->c);
 						console_flush(con);
 						buffer[nc++] = kev->c;
Index: uspace/lib/c/generic/io/chargrid.c
===================================================================
--- uspace/lib/c/generic/io/chargrid.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/c/generic/io/chargrid.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -140,5 +140,5 @@
  *
  */
-sysarg_t chargrid_putchar(chargrid_t *scrbuf, wchar_t ch, bool update)
+sysarg_t chargrid_putwchar(chargrid_t *scrbuf, wchar_t ch, bool update)
 {
 	assert(scrbuf->col < scrbuf->cols);
@@ -199,5 +199,5 @@
 
 	for (sysarg_t i = 0; i < spaces; i++)
-		flush += chargrid_putchar(scrbuf, ' ', true) - 1;
+		flush += chargrid_putwchar(scrbuf, ' ', true) - 1;
 
 	return flush;
@@ -228,10 +228,10 @@
 		scrbuf->row--;
 
-		chargrid_putchar(scrbuf, ' ', false);
+		chargrid_putwchar(scrbuf, ' ', false);
 		return 2;
 	}
 
 	scrbuf->col--;
-	chargrid_putchar(scrbuf, ' ', false);
+	chargrid_putwchar(scrbuf, ' ', false);
 	return 1;
 }
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/c/generic/io/io.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -46,4 +46,5 @@
 #include <ipc/loc.h>
 #include <adt/list.h>
+#include <wchar.h>
 #include "../private/io.h"
 #include "../private/stdio.h"
@@ -702,22 +703,40 @@
 }
 
-int fputc(wchar_t c, FILE *stream)
+wint_t fputwc(wchar_t wc, 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, 1, sz, stream);
-
-		if (wr < sz)
-			return EOF;
-
-		return (int) c;
-	}
-
-	return EOF;
-}
-
-int putchar(wchar_t c)
+	if (chr_encode(wc, buf, &sz, STR_BOUNDS(1)) != EOK) {
+		errno = EILSEQ;
+		return WEOF;
+	}
+
+	size_t wr = fwrite(buf, 1, sz, stream);
+	if (wr < sz)
+		return WEOF;
+
+	return wc;
+}
+
+wint_t putwchar(wchar_t wc)
+{
+	return fputwc(wc, stdout);
+}
+
+int fputc(int c, FILE *stream)
+{
+	unsigned char b;
+	size_t wr;
+
+	b = (unsigned char) c;
+	wr = fwrite(&b, sizeof(b), 1, stream);
+	if (wr < 1)
+		return EOF;
+
+	return b;
+}
+
+int putchar(int c)
 {
 	return fputc(c, stdout);
Index: uspace/lib/c/generic/io/vprintf.c
===================================================================
--- uspace/lib/c/generic/io/vprintf.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/c/generic/io/vprintf.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -54,5 +54,5 @@
 
 	while (offset < size) {
-		if (fputc(str[chars], (FILE *) stream) <= 0)
+		if (fputwc(str[chars], (FILE *) stream) <= 0)
 			break;
 
Index: uspace/lib/c/include/io/chargrid.h
===================================================================
--- uspace/lib/c/include/io/chargrid.h	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/c/include/io/chargrid.h	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -79,5 +79,5 @@
 extern sysarg_t chargrid_get_top_row(chargrid_t *);
 
-extern sysarg_t chargrid_putchar(chargrid_t *, wchar_t, bool);
+extern sysarg_t chargrid_putwchar(chargrid_t *, wchar_t, bool);
 extern sysarg_t chargrid_newline(chargrid_t *);
 extern sysarg_t chargrid_tabstop(chargrid_t *, sysarg_t);
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/c/include/stdio.h	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -40,4 +40,5 @@
 #include <_bits/size_t.h>
 #include <_bits/wchar_t.h>
+#include <_bits/wint_t.h>
 
 #define EOF  (-1)
@@ -73,13 +74,14 @@
 
 /* Character and string output functions */
-extern int fputc(wchar_t, FILE *);
+extern int fputc(int, FILE *);
 extern int fputs(const char *, FILE *);
 
-// FIXME: putchar and fputc are byte-oriented.
-// They shouldn't accept wide characters.
-extern int putchar(wchar_t);
+extern int putchar(int);
 extern int puts(const char *);
 
 extern int ungetc(int, FILE *);
+
+extern wint_t fputwc(wchar_t, FILE *);
+extern wint_t putwchar(wchar_t);
 
 /* Formatted string output functions */
Index: uspace/lib/c/include/wchar.h
===================================================================
--- uspace/lib/c/include/wchar.h	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/c/include/wchar.h	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -44,4 +44,5 @@
 #include <_bits/wchar_t.h>
 #include <_bits/wint_t.h>
+#include <_bits/WEOF.h>
 
 #include <_bits/NULL.h>
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/clui/tinput.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -145,5 +145,5 @@
 
 	for (p = 0; p < pad; p++)
-		putchar(' ');
+		putwchar(' ');
 
 	console_flush(ti->console);
@@ -182,5 +182,5 @@
 	tinput_console_set_lpos(ti, ti->text_coord + ti->nc);
 	console_flush(ti->console);
-	putchar('\n');
+	putwchar('\n');
 }
 
Index: uspace/lib/fmtutil/fmtutil.c
===================================================================
--- uspace/lib/fmtutil/fmtutil.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/fmtutil/fmtutil.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -95,14 +95,14 @@
 		for (i = 0; i < width; i++) {
 			if (i < len)
-				putchar(wstr[i]);
+				putwchar(wstr[i]);
 			else
-				putchar(' ');
+				putwchar(' ');
 		}
 	} else if (mode == ALIGN_RIGHT) {
 		for (i = 0; i < width; i++) {
 			if (i < width - len)
-				putchar(' ');
+				putwchar(' ');
 			else
-				putchar(wstr[i - (width - len)]);
+				putwchar(wstr[i - (width - len)]);
 		}
 	} else if (mode == ALIGN_CENTER) {
@@ -110,7 +110,7 @@
 		for (i = 0; i < width; i++) {
 			if ((i < padding) || ((i - padding) >= len))
-				putchar(' ');
+				putwchar(' ');
 			else
-				putchar(wstr[i - padding]);
+				putwchar(wstr[i - padding]);
 		}
 	} else if (mode == ALIGN_JUSTIFY) {
@@ -146,10 +146,10 @@
 				    (words - 1)));
 				for (j = 0; j < spaces; j++) {
-					putchar(' ');
+					putwchar(' ');
 				}
 				done_chars += spaces;
 			}
 			while (i < len && wstr[i] != ' ') {
-				putchar(wstr[i++]);
+				putwchar(wstr[i++]);
 				done_chars++;
 			}
@@ -158,5 +158,5 @@
 	skip_words:
 		while (done_chars < width) {
-			putchar(' ');
+			putwchar(' ');
 			done_chars++;
 		}
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/gui/terminal.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -456,5 +456,5 @@
 		break;
 	default:
-		updated = chargrid_putchar(term->frontbuf, ch, true);
+		updated = chargrid_putwchar(term->frontbuf, ch, true);
 	}
 
Index: uspace/lib/posix/include/posix/stdio.h
===================================================================
--- uspace/lib/posix/include/posix/stdio.h	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/lib/posix/include/posix/stdio.h	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -75,8 +75,8 @@
 extern char *gets(char *, size_t);
 
-extern int fputc(wchar_t, FILE *);
+extern int fputc(int, FILE *);
 extern int fputs(const char *, FILE *);
 
-extern int putchar(wchar_t);
+extern int putchar(int);
 extern int puts(const char *);
 
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/srv/hid/console/console.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -311,5 +311,5 @@
 		break;
 	default:
-		updated = chargrid_putchar(cons->frontbuf, ch, true);
+		updated = chargrid_putwchar(cons->frontbuf, ch, true);
 	}
 
Index: uspace/srv/hid/output/ctl/serial.c
===================================================================
--- uspace/srv/hid/output/ctl/serial.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/srv/hid/output/ctl/serial.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -57,5 +57,5 @@
 	vt100_goto(state, col, row);
 	vt100_set_attr(state, field->attrs);
-	vt100_putchar(state, field->ch);
+	vt100_putwchar(state, field->ch);
 }
 
@@ -122,9 +122,9 @@
 };
 
-errno_t serial_init(vt100_putchar_t putchar_fn,
+errno_t serial_init(vt100_putwchar_t putwchar_fn,
     vt100_control_puts_t control_puts_fn, vt100_flush_t flush_fn)
 {
 	vt100_state_t *state =
-	    vt100_state_create(SERIAL_COLS, SERIAL_ROWS, putchar_fn,
+	    vt100_state_create(SERIAL_COLS, SERIAL_ROWS, putwchar_fn,
 	    control_puts_fn, flush_fn);
 	if (state == NULL)
Index: uspace/srv/hid/output/ctl/serial.h
===================================================================
--- uspace/srv/hid/output/ctl/serial.h	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/srv/hid/output/ctl/serial.h	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -36,5 +36,5 @@
 #include "../proto/vt100.h"
 
-extern errno_t serial_init(vt100_putchar_t, vt100_control_puts_t, vt100_flush_t);
+extern errno_t serial_init(vt100_putwchar_t, vt100_control_puts_t, vt100_flush_t);
 
 #endif
Index: uspace/srv/hid/output/port/chardev.c
===================================================================
--- uspace/srv/hid/output/port/chardev.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/srv/hid/output/port/chardev.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -77,5 +77,5 @@
 }
 
-static void chardev_putchar(wchar_t ch)
+static void chardev_putwchar(wchar_t ch)
 {
 	if (chardev_bused == chardev_buf_size)
@@ -92,5 +92,5 @@
 	p = str;
 	while (*p != '\0')
-		chardev_putchar(*p++);
+		chardev_putwchar(*p++);
 }
 
@@ -198,5 +198,5 @@
 	}
 
-	serial_init(chardev_putchar, chardev_control_puts, chardev_flush);
+	serial_init(chardev_putwchar, chardev_control_puts, chardev_flush);
 
 	discovery_finished = true;
Index: uspace/srv/hid/output/proto/vt100.c
===================================================================
--- uspace/srv/hid/output/proto/vt100.c	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/srv/hid/output/proto/vt100.c	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -139,5 +139,5 @@
 
 vt100_state_t *vt100_state_create(sysarg_t cols, sysarg_t rows,
-    vt100_putchar_t putchar_fn, vt100_control_puts_t control_puts_fn,
+    vt100_putwchar_t putwchar_fn, vt100_control_puts_t control_puts_fn,
     vt100_flush_t flush_fn)
 {
@@ -146,5 +146,5 @@
 		return NULL;
 
-	state->putchar = putchar_fn;
+	state->putwchar = putwchar_fn;
 	state->control_puts = control_puts_fn;
 	state->flush = flush_fn;
@@ -219,7 +219,7 @@
 }
 
-void vt100_putchar(vt100_state_t *state, wchar_t ch)
-{
-	state->putchar(ch == 0 ? ' ' : ch);
+void vt100_putwchar(vt100_state_t *state, wchar_t ch)
+{
+	state->putwchar(ch == 0 ? ' ' : ch);
 	state->cur_col++;
 
Index: uspace/srv/hid/output/proto/vt100.h
===================================================================
--- uspace/srv/hid/output/proto/vt100.h	(revision a57fa325b051d5e952ced94f3f203b231c8f259a)
+++ uspace/srv/hid/output/proto/vt100.h	(revision ed88c8e9e48e792fdd0df46568e33e36eb624db3)
@@ -35,5 +35,5 @@
 #include <io/charfield.h>
 
-typedef void (*vt100_putchar_t)(wchar_t ch);
+typedef void (*vt100_putwchar_t)(wchar_t ch);
 typedef void (*vt100_control_puts_t)(const char *str);
 typedef void (*vt100_flush_t)(void);
@@ -47,10 +47,10 @@
 	char_attrs_t cur_attrs;
 
-	vt100_putchar_t putchar;
+	vt100_putwchar_t putwchar;
 	vt100_control_puts_t control_puts;
 	vt100_flush_t flush;
 } vt100_state_t;
 
-extern vt100_state_t *vt100_state_create(sysarg_t, sysarg_t, vt100_putchar_t,
+extern vt100_state_t *vt100_state_create(sysarg_t, sysarg_t, vt100_putwchar_t,
     vt100_control_puts_t, vt100_flush_t);
 extern void vt100_state_destroy(vt100_state_t *);
@@ -63,5 +63,5 @@
 extern void vt100_set_attr(vt100_state_t *, char_attrs_t);
 extern void vt100_cursor_visibility(vt100_state_t *, bool);
-extern void vt100_putchar(vt100_state_t *, wchar_t);
+extern void vt100_putwchar(vt100_state_t *, wchar_t);
 extern void vt100_flush(vt100_state_t *);
 
