Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/arch/arm32/src/arm32.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -63,6 +63,6 @@
 		init.tasks[i].addr = bootinfo->tasks[i].addr;
 		init.tasks[i].size = bootinfo->tasks[i].size;
-		str_ncpy(init.tasks[i].name, bootinfo->tasks[i].name,
-			CONFIG_TASK_NAME_BUFLEN);
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo->tasks[i].name);
 	}
 }
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/arch/ia64/src/ia64.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -88,6 +88,6 @@
 		    VRN_MASK;
 		init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
-		str_ncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name,
-			CONFIG_TASK_NAME_BUFLEN);
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo->taskmap.tasks[i].name);
 	}
 }
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/arch/mips32/src/mips32.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -92,6 +92,6 @@
 		init.tasks[i].addr = bootinfo->tasks[i].addr;
 		init.tasks[i].size = bootinfo->tasks[i].size;
-		str_ncpy(init.tasks[i].name, bootinfo->tasks[i].name,
-			CONFIG_TASK_NAME_BUFLEN);
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo->tasks[i].name);
 	}
 	
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/arch/ppc32/src/ppc32.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -62,6 +62,6 @@
 		init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
 		init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
-		str_ncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name,
-			CONFIG_TASK_NAME_BUFLEN);
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo.taskmap.tasks[i].name);
 	}
 }
Index: kernel/arch/sparc64/src/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sparc64.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/arch/sparc64/src/sparc64.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -62,6 +62,6 @@
 		init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr;
 		init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
-		str_ncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name,
-			CONFIG_TASK_NAME_BUFLEN);
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo.taskmap.tasks[i].name);
 	}
 	
Index: kernel/genarch/src/multiboot/multiboot.c
===================================================================
--- kernel/genarch/src/multiboot/multiboot.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/genarch/src/multiboot/multiboot.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -70,5 +70,5 @@
 	
 	/* Copy the command. */
-	str_ncpy(buf, start, min(sz, (size_t) (end - start) + 1));
+	str_ncpy(buf, sz, start, (size_t) (end - start));
 }
 
Index: kernel/generic/include/string.h
===================================================================
--- kernel/generic/include/string.h	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/generic/include/string.h	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -87,5 +87,6 @@
 extern int str_lcmp(const char *s1, const char *s2, count_t max_len);
 
-extern void str_ncpy(char *dst, const char *src, size_t size);
+extern void str_cpy(char *dest, size_t size, const char *src);
+extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
 extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/generic/src/console/kconsole.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -215,5 +215,5 @@
 	while ((hint = cmdtab_search_one(name, &pos))) {
 		if ((found == 0) || (str_length(output) > str_length(hint)))
-			str_ncpy(output, hint, MAX_CMDLINE);
+			str_cpy(output, MAX_CMDLINE, hint);
 		
 		pos = pos->next;
@@ -232,5 +232,5 @@
 	
 	if (found > 0)
-		str_ncpy(input, output, size);
+		str_cpy(input, size, output);
 	
 	return found;
@@ -439,5 +439,5 @@
 	if ((text[0] < '0') || (text[0] > '9')) {
 		char symname[MAX_SYMBOL_NAME];
-		str_ncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME));
+		str_ncpy(symname, MAX_SYMBOL_NAME, text, len + 1);
 		
 		uintptr_t symaddr;
@@ -581,6 +581,6 @@
 		case ARG_TYPE_STRING:
 			buf = (char *) cmd->argv[i].buffer;
-			str_ncpy(buf, cmdline + start,
-			    min((end - start) + 1, cmd->argv[i].len));
+			str_ncpy(buf, cmd->argv[i].len, cmdline + start,
+			    (end - start) + 1);
 			break;
 		case ARG_TYPE_INT:
@@ -593,6 +593,7 @@
 				if (cmdline[end - 1] == '"') {
 					buf = (char *) cmd->argv[i].buffer;
-					str_ncpy(buf, cmdline + start + 1,
-					    min((end - start) - 1, cmd->argv[i].len));
+					str_ncpy(buf, cmd->argv[i].len,
+					    cmdline + start + 1,
+					    (end - start) - 1);
 					cmd->argv[i].intval = (unative_t) buf;
 					cmd->argv[i].vartype = ARG_TYPE_STRING;
Index: kernel/generic/src/debug/symtab.c
===================================================================
--- kernel/generic/src/debug/symtab.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/generic/src/debug/symtab.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -226,5 +226,5 @@
 	while ((hint = symtab_search_one(name, &pos))) {
 		if ((found == 0) || (str_length(output) > str_length(hint)))
-			str_ncpy(output, hint, MAX_SYMBOL_NAME);
+			str_cpy(output, MAX_SYMBOL_NAME, hint);
 		
 		pos++;
@@ -242,5 +242,5 @@
 	
 	if (found > 0)
-		str_ncpy(input, output, size);
+		str_cpy(input, size, output);
 	
 	return found;
Index: kernel/generic/src/lib/string.c
===================================================================
--- kernel/generic/src/lib/string.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/generic/src/lib/string.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -529,36 +529,69 @@
 }
 
-/** Copy NULL-terminated string.
- *
- * Copy source string @a src to destination buffer @a dst.
- * No more than @a size bytes are written. NULL-terminator is always
- * written after the last succesfully copied character (i.e. if the
- * destination buffer is has at least 1 byte, it will be always
- * NULL-terminated).
- *
- * @param src   Source string.
+/** Copy string.
+ *
+ * Copy source string @a src to destination buffer @a dest.
+ * No more than @a size bytes are written. If the size of the output buffer
+ * is at least one byte, the output string will always be well-formed, i.e.
+ * null-terminated and containing only complete characters.
+ *
  * @param dst   Destination buffer.
  * @param count Size of the destination buffer.
- *
- */
-void str_ncpy(char *dst, const char *src, size_t size)
-{
-	/* No space for the NULL-terminator in the buffer */
+ * @param src   Source string.
+ */
+void str_cpy(char *dest, size_t size, const char *src)
+{
+	wchar_t ch;
+	size_t src_off;
+	size_t dest_off;
+
+	/* No space for the NULL-terminator in the buffer. */
 	if (size == 0)
 		return;
 	
+	src_off = 0;
+	dest_off = 0;
+
+	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
+			break;
+	}
+
+	dest[dest_off] = '\0';
+}
+
+/** Copy size-limited substring.
+ *
+ * Copy source string @a src to destination buffer @a dest.
+ * No more than @a size bytes are written. If the size of the output buffer
+ * is at least one byte, the output string will always be well-formed, i.e.
+ * null-terminated and containing only complete characters.
+ *
+ * No more than @a n bytes are read from the input string, so it does not
+ * have to be null-terminated.
+ *
+ * @param dst   Destination buffer.
+ * @param count Size of the destination buffer.
+ * @param src   Source string.
+ */
+void str_ncpy(char *dest, size_t size, const char *src, size_t n)
+{
 	wchar_t ch;
-	size_t str_off = 0;
-	size_t dst_off = 0;
-	
-	while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) {
-		if (chr_encode(ch, dst, &dst_off, size) != EOK)
+	size_t src_off;
+	size_t dest_off;
+
+	/* No space for the null terminator in the buffer. */
+	if (size == 0)
+		return;
+	
+	src_off = 0;
+	dest_off = 0;
+
+	while ((ch = str_decode(src, &src_off, n)) != 0) {
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-	
-	if (dst_off >= size)
-		dst[size - 1] = 0;
-	else
-		dst[dst_off] = 0;
+
+	dest[dest_off] = '\0';
 }
 
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/generic/src/main/kinit.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -191,8 +191,8 @@
 		
 		ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN);
-		str_ncpy(namebuf, INIT_PREFIX, TASK_NAME_BUFLEN);
-		str_ncpy(namebuf + INIT_PREFIX_LEN, name,
-		    TASK_NAME_BUFLEN - INIT_PREFIX_LEN);
-		
+		str_cpy(namebuf, TASK_NAME_BUFLEN, INIT_PREFIX);
+		str_cpy(namebuf + INIT_PREFIX_LEN,
+		    TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name);
+
 		int rc = program_create_from_image((void *) init.tasks[i].addr,
 		    namebuf, &programs[i]);
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 095003a87225b672e2979a6de2d669667aa1d735)
+++ kernel/generic/src/proc/task.c	(revision f4b153529231867ef6c64403a465d1f66e1016ca)
@@ -274,6 +274,6 @@
 		return (unative_t) rc;
 
-	namebuf[name_len] = 0;
-	str_ncpy(TASK->name, namebuf, TASK_NAME_BUFLEN);
+	namebuf[name_len] = '\0';
+	str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
 
 	return EOK;
