strlcpy.h: Add STRLCPY() macro

It wraps strlcpy(3bsd) so that it performs some steps that one might
forget, or might be prone to accidents:

-  It calculates the size of the destination buffer, and makes sure it's
   an array (otherwise, using sizeof(dst) would be very bad).

-  It calculates if there's truncation, returning an easy-to-use value.

BTW, this macro doesn't have any issues of double evaluation, because
sizeof() doesn't evaluate its argument (unless it's a VLA, but then
the static_assert(3) within SIZEOF_ARRAY() makes sure VLAs are not
allowed).

Cc: Christian Göttsche <cgzones@googlemail.com>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
Alejandro Colomar
2023-07-29 17:21:24 +02:00
committed by Iker Pedrosa
parent b1b5c46668
commit 33abc8bcd9
2 changed files with 57 additions and 0 deletions

View File

@@ -140,6 +140,7 @@ libshadow_la_SOURCES = \
stpecpy.h \
stpeprintf.c \
stpeprintf.h \
strlcpy.h \
strtoday.c \
sub.c \
subordinateio.h \

56
lib/strlcpy.h Normal file
View File

@@ -0,0 +1,56 @@
/*
* SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SHADOW_INCLUDE_LIB_STRLCPY_H_
#define SHADOW_INCLUDE_LIB_STRLCPY_H_
#include <config.h>
#include <stddef.h>
#include <string.h>
#include "sizeof.h"
/*
* SYNOPSIS
* int STRLCPY(char dst[restrict], const char *restrict src);
*
* ARGUMENTS
* dst Destination buffer where to copy a string.
* src Source string to be copied into dst.
*
* DESCRIPTION
* This macro copies the string pointed to by src, into a string
* at the buffer pointed to by dst. If the destination buffer,
* isn't large enough to hold the copy, the resulting string is
* truncated. The size of the buffer is calculated internally via
* SIZEOF_ARRAY().
*
* RETURN VALUE
* -1 If this call truncated the resulting string.
*
* strlen(dst)
* On success.
*
* ERRORS
* This function doesn't set errno.
*/
#define STRLCPY(dst, src) \
({ \
size_t sz_, len_; \
\
sz_ = SIZEOF_ARRAY(dst); \
len_ = strlcpy(dst, src, sz_); \
\
(len_ >= sz_) ? -1 : len_; \
})
#endif // include guard