Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision c4bbca86cdf88c7dc61d013838823a08cde1be3b)
+++ uspace/lib/c/generic/str.c	(revision 2fb88ea9613f1b88d0a533fd77265eca2c7a6218)
@@ -587,4 +587,47 @@
 	}
 
+	dest[dest_off] = '\0';
+	return rc;
+}
+
+/** Convert UTF16 string to string.
+ *
+ * Convert utf16 string @a src to string. The output is written to the buffer
+ * specified by @a dest and @a size. @a size must be non-zero and the string
+ * written will always be well-formed. Surrogate pairs also supported.
+ *
+ * @param dest	Destination buffer.
+ * @param size	Size of the destination buffer.
+ * @param src	Source utf16 string.
+ *
+ * @return EOK, if success, negative otherwise.
+ */
+int utf16_to_str(char *dest, size_t size, const uint16_t *src)
+{
+	size_t idx=0, dest_off=0;
+	wchar_t ch;
+	int rc = EOK;
+
+	/* There must be space for a null terminator in the buffer. */
+	assert(size > 0);
+
+	while (src[idx]) {
+		if ((src[idx] & 0xfc00) == 0xd800) {
+			if (src[idx+1] && (src[idx+1] & 0xfc00) == 0xdc00) {
+				ch = 0x10000;
+				ch += (src[idx] & 0x03FF) << 10;
+				ch += (src[idx+1] & 0x03FF);
+				idx += 2;
+			}
+			else
+				break;
+		} else {
+			ch = src[idx];
+			idx++;
+		}
+		rc = chr_encode(ch, dest, &dest_off, size-1);
+		if (rc != EOK)
+			break;
+	}
 	dest[dest_off] = '\0';
 	return rc;
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision c4bbca86cdf88c7dc61d013838823a08cde1be3b)
+++ uspace/lib/c/include/str.h	(revision 2fb88ea9613f1b88d0a533fd77265eca2c7a6218)
@@ -78,4 +78,5 @@
 extern char *wstr_to_astr(const wchar_t *src);
 extern int str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
+extern int utf16_to_str(char *dest, size_t size, const uint16_t *src);
 
 extern char *str_chr(const char *str, wchar_t ch);
