xref: /netbsd-src/common/lib/libc/string/strlcpy.c (revision 2dd10e69e37fb0959c0d785c93ea18efddb585bb)
1*2dd10e69Sriastradh /*	$NetBSD: strlcpy.c,v 1.4 2024/11/01 21:11:37 riastradh Exp $	*/
237c9f0a6Schristos /*	$OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $	*/
337c9f0a6Schristos 
437c9f0a6Schristos /*
537c9f0a6Schristos  * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
637c9f0a6Schristos  *
737c9f0a6Schristos  * Permission to use, copy, modify, and distribute this software for any
837c9f0a6Schristos  * purpose with or without fee is hereby granted, provided that the above
937c9f0a6Schristos  * copyright notice and this permission notice appear in all copies.
1037c9f0a6Schristos  *
1137c9f0a6Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
1237c9f0a6Schristos  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
1337c9f0a6Schristos  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
1437c9f0a6Schristos  * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1537c9f0a6Schristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
1637c9f0a6Schristos  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1737c9f0a6Schristos  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1837c9f0a6Schristos  */
1937c9f0a6Schristos 
2037c9f0a6Schristos #if !defined(_KERNEL) && !defined(_STANDALONE)
2137c9f0a6Schristos #if HAVE_NBTOOL_CONFIG_H
2237c9f0a6Schristos #include "nbtool_config.h"
2337c9f0a6Schristos #endif
2437c9f0a6Schristos 
2537c9f0a6Schristos #include <sys/cdefs.h>
2637c9f0a6Schristos #if defined(LIBC_SCCS) && !defined(lint)
27*2dd10e69Sriastradh __RCSID("$NetBSD: strlcpy.c,v 1.4 2024/11/01 21:11:37 riastradh Exp $");
2837c9f0a6Schristos #endif /* LIBC_SCCS and not lint */
2937c9f0a6Schristos 
3037c9f0a6Schristos #ifdef _LIBC
3137c9f0a6Schristos #include "namespace.h"
3237c9f0a6Schristos #endif
3337c9f0a6Schristos #include <sys/types.h>
3437c9f0a6Schristos #include <assert.h>
3537c9f0a6Schristos #include <string.h>
3637c9f0a6Schristos 
3737c9f0a6Schristos #ifdef _LIBC
3837c9f0a6Schristos # ifdef __weak_alias
3937c9f0a6Schristos __weak_alias(strlcpy, _strlcpy)
4037c9f0a6Schristos # endif
4137c9f0a6Schristos #endif
4237c9f0a6Schristos #else
4337c9f0a6Schristos #include <lib/libkern/libkern.h>
4437c9f0a6Schristos #endif /* !_KERNEL && !_STANDALONE */
4537c9f0a6Schristos 
4637c9f0a6Schristos 
4737c9f0a6Schristos #if !HAVE_STRLCPY
4837c9f0a6Schristos /*
4937c9f0a6Schristos  * Copy src to string dst of size siz.  At most siz-1 characters
5037c9f0a6Schristos  * will be copied.  Always NUL terminates (unless siz == 0).
5137c9f0a6Schristos  * Returns strlen(src); if retval >= siz, truncation occurred.
5237c9f0a6Schristos  */
5337c9f0a6Schristos size_t
54*2dd10e69Sriastradh strlcpy(char *__restrict dst, const char *__restrict src, size_t siz)
5537c9f0a6Schristos {
5637c9f0a6Schristos 	char *d = dst;
5737c9f0a6Schristos 	const char *s = src;
5837c9f0a6Schristos 	size_t n = siz;
5937c9f0a6Schristos 
6037c9f0a6Schristos 	_DIAGASSERT(dst != NULL);
6137c9f0a6Schristos 	_DIAGASSERT(src != NULL);
6237c9f0a6Schristos 
6337c9f0a6Schristos 	/* Copy as many bytes as will fit */
6437c9f0a6Schristos 	if (n != 0 && --n != 0) {
6537c9f0a6Schristos 		do {
6637c9f0a6Schristos 			if ((*d++ = *s++) == 0)
6737c9f0a6Schristos 				break;
6837c9f0a6Schristos 		} while (--n != 0);
6937c9f0a6Schristos 	}
7037c9f0a6Schristos 
7137c9f0a6Schristos 	/* Not enough room in dst, add NUL and traverse rest of src */
7237c9f0a6Schristos 	if (n == 0) {
7337c9f0a6Schristos 		if (siz != 0)
7437c9f0a6Schristos 			*d = '\0';		/* NUL-terminate dst */
7537c9f0a6Schristos 		while (*s++)
7637c9f0a6Schristos 			;
7737c9f0a6Schristos 	}
7837c9f0a6Schristos 
7937c9f0a6Schristos 	return(s - src - 1);	/* count does not include NUL */
8037c9f0a6Schristos }
8137c9f0a6Schristos #endif
82