GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-602118adcc
strlcat.c
Go to the documentation of this file.
1 /*!
2  * \file lib/gis/strlcat.c
3  *
4  * \brief GIS Library - GRASS implementation of strlcat().
5  *
6  * If available, G_strlcat() calls system strlcat(), otherwise it uses
7  * implementation by Todd C. Miller of OpenBSD.
8  *
9  * Addition to GRASS GIS by Nicklas Larsson, 2024
10  *
11  * Original OpenBSD implementation notes:
12  *
13  * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
14  *
15  * Permission to use, copy, modify, and distribute this software for any
16  * purpose with or without fee is hereby granted, provided that the above
17  * copyright notice and this permission notice appear in all copies.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
20  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
22  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26  */
27 
28 #include <stddef.h>
29 #include <string.h>
30 
31 static size_t G__strlcat(char *restrict dst, const char *restrict src,
32  size_t dsize);
33 
34 /**
35  * \brief Size-bounded string concatenation
36  *
37  * Appends string src to the end of dst. It will append at most
38  * dstsize - strlen(dst) - 1 characters. It will then NUL-terminate, unless
39  * dstsize is 0 or the original dst string was longer than dstsize (in practice
40  * this should not happen as it means that either dstsize is incorrect or that
41  * dst is not a proper string).
42  *
43  * If the src and dst strings overlap, the behavior is undefined.
44  * This function is a safer alternative to strncat.
45  *
46  * \param[out] dst Pointer to the destination buffer. Must be a NUL-terminated
47  * C string.
48  * \param[in] src Pointer to the source string, which will be appended. Must
49  * be a NUL-terminated C string.
50  * \param[in] dsize The size of the destination buffer.
51  *
52  * \return The total length of the string src, which was attempted to be
53  * created (the initial length of dst plus the length of src, not
54  * including the terminating NUL character). If the return value
55  * is >= dsize, truncation occurred.
56  */
57 size_t G_strlcat(char *dst, const char *src, size_t dsize)
58 {
59 #ifdef HAVE_STRLCAT
60  return strlcat(dst, src, dsize);
61 #else
62  return G__strlcat(dst, src, dsize);
63 #endif
64 }
65 
66 static size_t G__strlcat(char *restrict dst, const char *restrict src,
67  size_t dsize)
68 {
69  const char *odst = dst;
70  const char *osrc = src;
71  size_t n = dsize;
72  size_t dlen;
73 
74  /* Find the end of dst and adjust bytes left but don't go past end. */
75  while (n-- != 0 && *dst != '\0')
76  dst++;
77  dlen = dst - odst;
78  n = dsize - dlen;
79 
80  if (n-- == 0)
81  return (dlen + strlen(src));
82  while (*src != '\0') {
83  if (n != 0) {
84  *dst++ = *src;
85  n--;
86  }
87  src++;
88  }
89  *dst = '\0';
90 
91  return (dlen + (src - osrc)); /* count does not include NUL */
92 }
char * dst
Definition: lz4.h:981
const char * src
Definition: lz4.h:989
size_t G_strlcat(char *dst, const char *src, size_t dsize)
Size-bounded string concatenation.
Definition: strlcat.c:57