summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlejandro Colomar <alx.manpages@gmail.com>2022-09-05 17:03:30 +0200
committerAlejandro Colomar <alx@kernel.org>2022-12-02 14:31:57 +0100
commitd71769b802d54fca3218526ae679a16c2b5bab90 (patch)
tree2cbf10fbef6a94c2090ac2cf61c73d60188c62bd
parent33f7aa3fe42aa92bfac21e3c2201ae6d844cf6f8 (diff)
stpecpy.c: Add string copy function similar to strlcpy(3bsd)strlcpy
This function behaves like strlcpy(3bsd) and strlcat(3bsd), except that it is faster. - It doesn't need to traverse the whole dest string for concatenation. - The user doesn't need to recalculate the buffer remaining size for concatenation (that's an issue with strcpy(3bsd), when tried to use instead of strlcat(3bsd) to overcome performance issues). This function only has an (obvious) issue compared to strlcpy(3bsd)/strlcat(3bsd): When the memory is realloc(3)ated, the end pointer needs to be recalculated. In those cases, it is safer to use the BSD functions, even if slightly slower. Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
-rw-r--r--lib/prototypes.h3
-rw-r--r--libmisc/stpecpy.c76
2 files changed, 79 insertions, 0 deletions
diff --git a/lib/prototypes.h b/lib/prototypes.h
index 8026af77..801512a3 100644
--- a/lib/prototypes.h
+++ b/lib/prototypes.h
@@ -428,6 +428,9 @@ extern int shell (const char *file, /*@null@*/const char *arg, char *const envp[
extern int run_command (const char *cmd, const char *argv[],
/*@null@*/const char *envp[], /*@out@*/int *status);
+/* stpecpy.c */
+extern char *shdw_stpecpy(char *dst, const char *restrict src, const char *end);
+
/* strscpy.c */
ssize_t strscpy (char *restrict dst, const char *restrict src, size_t n);
diff --git a/libmisc/stpecpy.c b/libmisc/stpecpy.c
new file mode 100644
index 00000000..1f7e1f94
--- /dev/null
+++ b/libmisc/stpecpy.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022, Alejandro Colomar <alx.manpages@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the copyright holders or contributors may not be used to
+ * endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ident "$Id$"
+
+#include "prototypes.h"
+
+
+/*
+ * ARGUMENTS
+ * dst Pointer to the first byte of the destination buffer.
+ *
+ * src Pointer to the first byte of the source string.
+ *
+ * end Pointer to one-past-the-end of the 'dst' buffer.
+ *
+ * DESCRIPTION
+ * This function reads the whole 'str' string, until a NUL
+ * character is found, and copies it (or the part of it that fits)
+ * into 'dst', guaranteeing that the resulting string is
+ * NUL-terminated.
+ *
+ * RETURN VALUE
+ * This function returns a pointer to the terminating NUL byte in
+ * the 'dst' string.
+ *
+ * CAVEATS
+ * This function silently truncates the source string if it
+ * doesn't fit in the 'dst'. This is desirable in many cases, and
+ * simplifies usage. If this is not wanted, other functions, such
+ * as strlcpy(3bsd) and strlcat(3bsd) may be preferred.
+ *
+ * This function requires that the input string is NUL-terminated.
+ * If this cannot be guaranteed, other functions should be used,
+ * such as strscpy().
+ *
+ * If the 'dst' buffer is a zero-sized array, that is, if
+ * 'dst == end', the behavior is undefined.
+ */
+
+char *
+stpecpy(char *dst, const char *restrict src, const char *end)
+{
+ for (/* void */; *src != '\0'; src++) {
+ if (dst < end)
+ *dst++ = *src;
+ }
+ if (dst < end)
+ *dst = '\0';
+ return dst;
+}