1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2025 Oxide Computer Company
14 */
15
16 /*
17 * Wide character version of strlcat(3C). This appends up to dstlen - 1 wide
18 * characters to dst, taking into account any string that already is present
19 * there. The resulting string is always terminated with a NULL wide-character
20 * unless the dst buffer is already full of data with no terminator. The number
21 * of wide characters that would be in the fully concatenated string is
22 * returned.
23 */
24
25 #include "lint.h"
26 #include <wchar.h>
27 #include <sys/sysmacros.h>
28
29 size_t
wcslcat(wchar_t * restrict dst,const wchar_t * restrict src,size_t dstlen)30 wcslcat(wchar_t *restrict dst, const wchar_t *restrict src, size_t dstlen)
31 {
32 size_t srclen = wcslen(src);
33 size_t dstoff = wcsnlen(dst, dstlen);
34 size_t nwcs;
35
36 /*
37 * If there is no space in the destination buffer for the source string,
38 * then do not do anything. We check both for the case where there is no
39 * valid NUL in dst (dstoff == dstlen) or where there is one, which
40 * means that there is nothing to actually copy. It's also possible that
41 * there was never any space to begin with.
42 */
43 if (dstlen == 0 || dstoff >= dstlen - 1) {
44 return (srclen + dstoff);
45 }
46
47 nwcs = MIN(dstlen - 1 - dstoff, srclen);
48 (void) wmemcpy(dst + dstoff, src, nwcs);
49 dst[nwcs + dstoff] = L'\0';
50 return (srclen + dstoff);
51 }
52