diff options
Diffstat (limited to 'lib/libzpool/kernel.c')
-rw-r--r-- | lib/libzpool/kernel.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 1f58acb04..1d4647094 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -956,6 +956,35 @@ kmem_asprintf(const char *fmt, ...) return (buf); } +/* + * kmem_scnprintf() will return the number of characters that it would have + * printed whenever it is limited by value of the size variable, rather than + * the number of characters that it did print. This can cause misbehavior on + * subsequent uses of the return value, so we define a safe version that will + * return the number of characters actually printed, minus the NULL format + * character. Subsequent use of this by the safe string functions is safe + * whether it is snprintf(), strlcat() or strlcpy(). + */ +int +kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...) +{ + int n; + va_list ap; + + /* Make the 0 case a no-op so that we do not return -1 */ + if (size == 0) + return (0); + + va_start(ap, fmt); + n = vsnprintf(str, size, fmt, ap); + va_end(ap); + + if (n >= size) + n = size - 1; + + return (n); +} + zfs_file_t * zfs_onexit_fd_hold(int fd, minor_t *minorp) { |