diff --git a/src/encode/utf8.c b/src/encode/utf8.c
index 56c5bd710f29cbc599c1f4e90e9c3fcf8576143a..20bae23fddb261dfea756090f21d3393dd7f8235 100644
--- a/src/encode/utf8.c
+++ b/src/encode/utf8.c
@@ -224,6 +224,28 @@ size_t utf8_str_count_width(const char* str, size_t min_width, size_t max_width)
 	return count;
 }
 
+// Like strlcpy(), but doesn't leave a partial UTF-8 sequence at the end of dst
+size_t utf8_strlcpy(char* dst, const char* src, size_t size)
+{
+	size_t i;
+	int len;
+
+	if (size < 1)
+		return 0;
+
+	for (i = 0; src[i] != '\0'; i += len) {
+		len = utf8_decode_firstbyte(src[i]);
+		if (len < 1)
+			break;
+		if(i + len  < size) {
+			memcpy(dst, src + i, len);
+			dst += len;
+		}
+	}
+	*dst = '\0';
+	return i;
+}
+
 int cp437_to_utf8_str(const char* str, char* dest, size_t maxlen, unsigned char minval)
 {
 	int retval = 0;
diff --git a/src/encode/utf8.h b/src/encode/utf8.h
index 99e8e50c62218e6c8c14da6856d45e90e24feb11..1bfd4fe645c9680f55578dd0481506d81d70379e 100644
--- a/src/encode/utf8.h
+++ b/src/encode/utf8.h
@@ -44,6 +44,9 @@ size_t utf8_str_total_width(const char*);
 // Return the count of chars within the specified width range in UTF-8 string (str)
 size_t utf8_str_count_width(const char*, size_t min_width, size_t max_width);
 
+// Like strlcpy(), but doesn't leave a partial UTF-8 sequence at the end of dst
+size_t utf8_strlcpy(char* dst, const char* src, size_t size);
+
 // Normalizes (to ASCII) chars in UTF-8 string 'str', in-place, resulting in string <= original in length
 char* utf8_normalize_str(char* str);