Your API is compatible with *BSD but I'm wondering whether something
slightly different might make error handling for callers easier:
Currently strlcpy returns the total length of the string it tried to
create, whether it was too long or not. This means a check whether the
complete string was copied is always something like
if (strlcpy(dest, src, sizeof(dest)) >= sizeof(dest))
goto toolong;
If strlcpy would return 0 for successful copies this would simplify to
if (!strlcpy(dest, src, sizeof(dest)))
goto toolong;
A patch is below.
I've tested only the compilation, any comments are welcome.
Another possible change to the semantics might be to copy/cat only if
dest is big enough to make error handling especially in the case of
strlcat easier (without additional information it's currently impossible
to get the original contents of dest if only parts of src were copied).
> Linus
cu
Adrian
--- linux-2.5.69/lib/string.c.old 2003-05-26 11:29:21.000000000 +0200
+++ linux-2.5.69/lib/string.c 2003-05-26 15:19:56.000000000 +0200
@@ -102,20 +102,30 @@
* @src: Where to copy the string from
* @size: size of destination buffer
*
- * Compatible with *BSD: the result is always a valid
+ * Similar to *BSD: the result is always a valid
* NUL-terminated string that fits in the buffer (unless,
* of course, the buffer size is zero). It does not pad
- * out the result like strncpy() does.
+ * out the result like strncpy() does. Unlike *BSD it
+ * returns 0 for a successful copy.
*/
size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = strlen(src);
+ size_t len;
+
+ if (!size)
+ return 0;
+
+ if (ret >= size)
+ len = size - 1;
+ else {
+ len = ret;
+ ret = 0;
+ }
+
+ memcpy(dest, src, len);
+ dest[len] = '\0';
- if (size) {
- size_t len = (ret >= size) ? size-1 : ret;
- memcpy(dest, src, len);
- dest[len] = '\0';
- }
return ret;
}
EXPORT_SYMBOL(strlcpy);
@@ -175,23 +185,33 @@
* @dest: The string to be appended to
* @src: The string to append to it
* @count: The size of the destination buffer.
+ *
+ * Returns 0 if successful, the number of bytes needed in dest
+ * otherwise.
*/
size_t strlcat(char *dest, const char *src, size_t count)
{
size_t dsize = strlen(dest);
size_t len = strlen(src);
- size_t res = dsize + len;
+ size_t ret;
/* This would be a bug */
BUG_ON(dsize >= count);
dest += dsize;
count -= dsize;
+
if (len >= count)
- len = count-1;
+ {
+ ret = dsize + len;
+ len = count - 1;
+ }
+ else
+ ret = 0;
+
memcpy(dest, src, len);
- dest[len] = 0;
- return res;
+ dest[len] = '\0';
+ return ret;
}
EXPORT_SYMBOL(strlcat);
#endif
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/