---
name: "ggstrlcat"
section: "3"
platform: "linux"
package: "libgii1"
version: "1:1.0.2-4.1"
release: "Debian 7 (Wheezy)"
platforms: ["linux"]
url: "https://new.carta.tech/ggstrlcpy"
---

# ggstrlcat(3)

size-bounded string copying and concatenation

Part of [ggstrlcpy(3)](/ggstrlcpy/3.md).

## NAME

**ggstrlcpy**, **ggstrlcat** - size-bounded string copying and concatenation

## SYNOPSIS

```
#include <ggi/gg.h>
size_t ggstrlcpy(char *dst, const char *src, size_t siz);
size_t ggstrlcat(char *dst, const char *src, size_t siz);
```

## DESCRIPTION

The **ggstrlcpy** and **ggstrlcat** functions copy and concatenate strings respectively.  They are designed to be safer, more consistent, and less error prone replacements for `strncpy(3)` and `strncat(3)`. Unlike those functions, **ggstrlcpy** and **ggstrlcat** take the full size of the buffer (not just the length) and guarantee to NUL-terminate the result (as long as size is larger than 0 or, in the case of **ggstrlcat**, as long as there is at least one byte free in *dst*).  Note that you should include a byte for the NUL in size.  Also note that **ggstrlcpy** and **ggstrlcat** only operate on true C strings.  This means that for **ggstrlcpy** *src* must be NUL-terminated and for **ggstrlcat** both *src* and *dst* must be NUL-terminated.

The **ggstrlcpy** function copies up to *siz* - 1 characters from the NUL-terminated string *src* to *dst*, NUL-terminating the result.

The **ggstrlcat** function appends the NUL-terminated string *src* to the end of *dst*.  It will append at most *siz* - strlen(*dst*) - 1 bytes, NUL-terminating the result.

## RETURN VALUES

The **ggstrlcpy** and **ggstrlcat** functions return the total length of the string they tried to create.  For **ggstrlcpy** that means the length of *src*. For **ggstrlcat** that means the initial length of *dst* plus the length of *src*.  While this may seem somewhat confusing it was done to make truncation detection simple.

Note however, that if **ggstrlcat** traverses size characters without finding a NUL, the length of the string is considered to be size and the destination string will not be NUL-terminated (since there was no space for the NUL).  This keeps **ggstrlcat** from running off the end of a string.  In practice this should not happen (as it means that either size is incorrect or that *dst* is not a proper C string).  The check exists to prevent potential security problems in incorrect code.

## EXAMPLES

The following code fragment illustrates the simple case:

```
char *s, *p, buf[BUFSIZ];
...
(void)ggstrlcpy(buf, s, sizeof(buf));
(void)ggstrlcat(buf, p, sizeof(buf));
```

To detect truncation, perhaps while building a pathname, something like the following might be used:

```
char *dir, *file, pname[MAXPATHLEN];
...
if (ggstrlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
        goto toolong;
if (ggstrlcat(pname, file, sizeof(pname)) >= sizeof(pname))
        goto toolong;
```

Since we know how many characters we copied the first time, we can speed things up a bit by using a copy instead of an append:

```
char *dir, *file, pname[MAXPATHLEN];
size_t n;
...
n = ggstrlcpy(pname, dir, sizeof(pname));
if (n >= sizeof(pname))
        goto toolong;
if (ggstrlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
        goto toolong;
```

However, one may question the validity of such optimizations, as they defeat the whole purpose of **ggstrlcpy** and **ggstrlcat**.

## SEE ALSO

`snprintf(3)` `strncat(3)` `strncpy(3)`

## HISTORY

**strlcpy** and **strlcat** first appeared in OpenBSD 2.4, then in NetBSD 1.4.3 and FreeBSD 3.3.0. **ggstrlcpy** and **ggstrlcat** has been added to libgg for portability.
