Add stpecpy()
strncat(3), strlcpy(3), and many other functions are often misused for catenating strings, when they should never be used for that. strlcat(3) is good. However, there's no equivalent to strlcat(3) similar to snprintf(3). Let's add stpecpy(), which is similar to strlcat(3), but it is also the only function compatible with stpeprintf(), which makes it more useful than strlcat(3). Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
parent
e0e9e57a72
commit
709e6b4497
@ -50,7 +50,7 @@ AC_CHECK_FUNCS(arc4random_buf futimes \
|
|||||||
initgroups lckpwdf lutimes mempcpy \
|
initgroups lckpwdf lutimes mempcpy \
|
||||||
setgroups updwtmp updwtmpx innetgr \
|
setgroups updwtmp updwtmpx innetgr \
|
||||||
getspnam_r \
|
getspnam_r \
|
||||||
memset_explicit explicit_bzero stpeprintf)
|
memset_explicit explicit_bzero stpecpy stpeprintf)
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
92
lib/stpecpy.h
Normal file
92
lib/stpecpy.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SHADOW_INCLUDE_LIB_STPECPY_H_
|
||||||
|
#define SHADOW_INCLUDE_LIB_STPECPY_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if !defined(HAVE_STPECPY)
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
|
|
||||||
|
inline char *stpecpy(char *dst, char *end, const char *restrict src);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SYNOPSIS
|
||||||
|
* char *_Nullable stpecpy(char *_Nullable dst, char end[0],
|
||||||
|
* const char *restrict src);
|
||||||
|
*
|
||||||
|
* ARGUMENTS
|
||||||
|
* dst Destination buffer where to copy a string.
|
||||||
|
*
|
||||||
|
* end Pointer to one after the last element of the buffer
|
||||||
|
* pointed to by `dst`. Usually, it should be calculated
|
||||||
|
* as `dst + NITEMS(dst)`.
|
||||||
|
*
|
||||||
|
* src Source string to be copied into dst.
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
* This function copies the string pointed to by src, into a string
|
||||||
|
* at the buffer pointed to by dst. If the destination buffer,
|
||||||
|
* limited by a pointer to its end --one after its last element--,
|
||||||
|
* isn't large enough to hold the copy, the resulting string is
|
||||||
|
* truncated.
|
||||||
|
*
|
||||||
|
* This function can be chained with calls to [v]stpeprintf().
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
* dst + strlen(dst)
|
||||||
|
* • On success, this function returns a pointer to the
|
||||||
|
* terminating NUL byte.
|
||||||
|
*
|
||||||
|
* end
|
||||||
|
* • If this call truncated the resulting string.
|
||||||
|
* • If `dst == end` (a previous chained call to these
|
||||||
|
* functions truncated).
|
||||||
|
* NULL
|
||||||
|
* • If `dst == NULL` (a previous chained call to
|
||||||
|
* [v]stpeprintf() failed).
|
||||||
|
*
|
||||||
|
* ERRORS
|
||||||
|
* This function doesn't set errno.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
inline char *
|
||||||
|
stpecpy(char *dst, char *end, const char *restrict src)
|
||||||
|
{
|
||||||
|
bool trunc;
|
||||||
|
char *p;
|
||||||
|
size_t dsize, dlen, slen;
|
||||||
|
|
||||||
|
if (dst == end)
|
||||||
|
return end;
|
||||||
|
if (dst == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dsize = end - dst;
|
||||||
|
slen = strnlen(src, dsize);
|
||||||
|
trunc = (slen == dsize);
|
||||||
|
dlen = slen - trunc;
|
||||||
|
|
||||||
|
p = mempcpy(dst, src, dlen);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
return p + trunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !HAVE_STPECPY
|
||||||
|
#endif // include guard
|
@ -62,6 +62,7 @@ libmisc_la_SOURCES = \
|
|||||||
setugid.c \
|
setugid.c \
|
||||||
setupenv.c \
|
setupenv.c \
|
||||||
shell.c \
|
shell.c \
|
||||||
|
stpecpy.c \
|
||||||
stpeprintf.c \
|
stpeprintf.c \
|
||||||
strtoday.c \
|
strtoday.c \
|
||||||
sub.c \
|
sub.c \
|
||||||
|
20
libmisc/stpecpy.c
Normal file
20
libmisc/stpecpy.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if !defined(HAVE_STPECPY)
|
||||||
|
|
||||||
|
#ident "$Id$"
|
||||||
|
|
||||||
|
#include "stpecpy.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern inline char *stpecpy(char *dst, char *end, const char *restrict src);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // !HAVE_STPECPY
|
Loading…
Reference in New Issue
Block a user