>From dc4a8d880cb3be138b96b682ae57a10259a67ba4 Mon Sep 17 00:00:00 2001
From: Bruno Haible
Date: Thu, 28 Sep 2017 00:30:05 +0200
Subject: [PATCH 1/2] New module 'strlcpy'.
* lib/string.in.h (_GL_ATTRIBUTE_RETURN_CHECK): New macro.
(strlcpy): New declaration.
* lib/strlcpy.c: New file.
* m4/strlcpy.m4: New file.
* modules/strlcpy: New file.
* m4/string_h.m4 (gl_HEADER_STRING_H_BODY): Test whether strlcpy is
declared.
(gl_HEADER_STRING_H_DEFAULTS): Initialize GNULIB_STRLCPY, HAVE_STRLCPY,
REPLACE_STRLCPY.
* modules/string (Makefile.am): Substitite GNULIB_STRLCPY, HAVE_STRLCPY,
REPLACE_STRLCPY.
* doc/gnulib.texi (BSD Function Substitutes): New chapter.
* doc/bsd-functions/strlcpy.texi: New file.
---
ChangeLog | 17 +++++++++++++
doc/bsd-functions/strlcpy.texi | 18 +++++++++++++
doc/gnulib.texi | 27 ++++++++++++++++++++
lib/string.in.h | 46 ++++++++++++++++++++++++++++++++++
lib/strlcpy.c | 57 ++++++++++++++++++++++++++++++++++++++++++
m4/string_h.m4 | 17 +++++++------
m4/strlcpy.m4 | 22 ++++++++++++++++
modules/string | 15 ++++++-----
modules/strlcpy | 26 +++++++++++++++++++
9 files changed, 232 insertions(+), 13 deletions(-)
create mode 100644 doc/bsd-functions/strlcpy.texi
create mode 100644 lib/strlcpy.c
create mode 100644 m4/strlcpy.m4
create mode 100644 modules/strlcpy
diff --git a/ChangeLog b/ChangeLog
index 8a9bbe6..c005f1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2017-09-27 Bruno Haible
+
+ New module 'strlcpy'.
+ * lib/string.in.h (_GL_ATTRIBUTE_RETURN_CHECK): New macro.
+ (strlcpy): New declaration.
+ * lib/strlcpy.c: New file.
+ * m4/strlcpy.m4: New file.
+ * modules/strlcpy: New file.
+ * m4/string_h.m4 (gl_HEADER_STRING_H_BODY): Test whether strlcpy is
+ declared.
+ (gl_HEADER_STRING_H_DEFAULTS): Initialize GNULIB_STRLCPY, HAVE_STRLCPY,
+ REPLACE_STRLCPY.
+ * modules/string (Makefile.am): Substitite GNULIB_STRLCPY, HAVE_STRLCPY,
+ REPLACE_STRLCPY.
+ * doc/gnulib.texi (BSD Function Substitutes): New chapter.
+ * doc/bsd-functions/strlcpy.texi: New file.
+
2017-09-26 Bruno Haible
uniname/uniname-tests: Tighten code.
diff --git a/doc/bsd-functions/strlcpy.texi b/doc/bsd-functions/strlcpy.texi
new file mode 100644
index 0000000..5ce05dc
--- /dev/null
+++ b/doc/bsd-functions/strlcpy.texi
@@ -0,0 +1,18 @@
address@hidden strlcpy
address@hidden @code{strlcpy}
address@hidden strlcpy
+
+Gnulib module: strlcpy
+
+Portability problems fixed by Gnulib:
address@hidden
address@hidden
+This function is missing on some platforms:
+glibc 2.24, AIX 5.1, HP-UX 11, OSF/1 5.1, mingw, MSVC 14, BeOS.
address@hidden
+Ignoring the return value of this function does not produce a warning.
address@hidden itemize
+
+Portability problems not fixed by Gnulib:
address@hidden
address@hidden itemize
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index 1468c14..6a52787 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -69,6 +69,7 @@ Documentation License''.
* Legacy Function Substitutes:: Replacing system functions.
* Glibc Header File Substitutes:: Overriding system headers.
* Glibc Function Substitutes:: Replacing system functions.
+* BSD Function Substitutes:: Replacing system functions.
* Native Windows Support:: Support for the native Windows platforms.
* Particular Modules:: Documentation of individual modules.
* Regular expressions:: The regex module.
@@ -6306,6 +6307,32 @@ This list of functions is sorted according to the header that declares them.
@c @section Glibc Extensions to @code{}
address@hidden BSD Function Substitutes
address@hidden BSD Function Substitutes
+
+This chapter describes which functions and function-like macros provided
+as extensions by the common BSD systems (FreeBSD, NetBSD, OpenBSD) are
+also supported by Gnulib, which portability pitfalls are fixed by Gnulib,
+and which (known) portability problems are not worked around by Gnulib.
+
address@hidden function
+
+This list of functions is sorted according to the header that declares them.
+
address@hidden
+* BSD string.h::
address@hidden menu
+
address@hidden BSD string.h
address@hidden BSD Extensions to @code{}
+
address@hidden
+* strlcpy::
address@hidden menu
+
address@hidden bsd-functions/strlcpy.texi
+
+
@node Native Windows Support
@chapter Native Windows Support
diff --git a/lib/string.in.h b/lib/string.in.h
index eb5be69..e7d6f4b 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -60,6 +60,16 @@
# define _GL_ATTRIBUTE_PURE /* empty */
#endif
+/* Declares that the return value of a function should not be ignored by the
+ caller. The warn_unused_result attribute appeared first in gcc-3.4.0. */
+#ifndef _GL_ATTRIBUTE_RETURN_CHECK
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# define _GL_ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
+# else
+# define _GL_ATTRIBUTE_RETURN_CHECK
+# endif
+#endif
+
/* NetBSD 5.0 declares strsignal in , not in . */
/* But in any case avoid namespace pollution on glibc systems. */
#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \
@@ -1041,6 +1051,42 @@ _GL_WARN_ON_USE (strsignal, "strsignal is unportable - "
# endif
#endif
+/* Copies the string SRC, possibly truncated, into the bounded memory area
+ [DST,...,DST+DSTSIZE-1]. Returns strlen (SRC).
+ The result is truncated if and only if the return value is >= DSTSIZE.
+ The result is truncated without NUL terminator if and only if DSTSIZE == 0.
+ */
+#if @GNULIB_STRLCPY@
+# if @REPLACE_STRLCPY@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strlcpy
+# define strlcpy rpl_strlcpy
+# endif
+_GL_FUNCDECL_RPL (strlcpy, size_t,
+ (char *__dst, const char *__src, size_t __dstsize)
+ _GL_ARG_NONNULL ((1, 2))
+ _GL_ATTRIBUTE_RETURN_CHECK);
+_GL_CXXALIAS_RPL (strlcpy, size_t,
+ (char *__dst, const char *__src, size_t __dstsize));
+# else
+# if address@hidden@
+_GL_FUNCDECL_SYS (strlcpy, size_t,
+ (char *__dst, const char *__src, size_t __dstsize)
+ _GL_ARG_NONNULL ((1, 2))
+ _GL_ATTRIBUTE_RETURN_CHECK);
+# endif
+_GL_CXXALIAS_SYS (strlcpy, size_t,
+ (char *__dst, const char *__src, size_t __dstsize));
+# endif
+_GL_CXXALIASWARN (strlcpy);
+#elif defined GNULIB_POSIXCHECK
+# undef strndup
+# if HAVE_RAW_DECL_STRLCPY
+_GL_WARN_ON_USE (strlcpy, "strlcpy is unportable - "
+ "use gnulib module strlcpy for portability");
+# endif
+#endif
+
#if @GNULIB_STRVERSCMP@
# if address@hidden@
_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *)
diff --git a/lib/strlcpy.c b/lib/strlcpy.c
new file mode 100644
index 0000000..e6cb133
--- /dev/null
+++ b/lib/strlcpy.c
@@ -0,0 +1,57 @@
+/* Copy a string into a bounded memory area.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* Written by Bruno Haible , 2017. */
+
+#include
+
+/* Specification. */
+#include
+
+/* Copies the string SRC, possibly truncated, into the bounded memory area
+ [DST,...,DST+DSTSIZE-1]. Returns strlen (SRC).
+ The result is truncated if and only if the return value is >= DSTSIZE.
+ The result is truncated without NUL terminator if and only if DSTSIZE == 0.
+ */
+size_t
+strlcpy (char *dst, const char *src, size_t dstsize)
+#undef strlcpy
+{
+ /* The implementation in dietlibc is broken, says
+ . */
+#if HAVE_STRLCPY && !defined __dietlibc__
+ return strlcpy (dst, src, dstsize);
+#else
+ if (dstsize > 0)
+ {
+ /* This implementation makes only one pass through SRC, for cache
+ efficiency. */
+ char *p = dst;
+ while (--dstsize > 0)
+ {
+ char c = *src++;
+ *p = c;
+ if (c == '\0')
+ return p - dst;
+ p++;
+ }
+ *p = '\0';
+ return (p - dst) + strlen (src);
+ }
+ else
+ return strlen (src);
+#endif
+}
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index ac6311f..b8f68ce 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -5,7 +5,7 @@
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 21
+# serial 22
# Written by Paul Eggert.
@@ -29,7 +29,7 @@ AC_DEFUN([gl_HEADER_STRING_H_BODY],
]],
[ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul
strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r
- strerror_r strsignal strverscmp])
+ strerror_r strsignal strlcpy strverscmp])
])
AC_DEFUN([gl_STRING_MODULE_INDICATOR],
@@ -80,6 +80,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR])
GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R])
GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL])
+ GNULIB_STRLCPY=0; AC_SUBST([GNULIB_STRLCPY])
GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP])
HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN])
dnl Assume proper GNU behavior unless another module says otherwise.
@@ -103,20 +104,22 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R])
HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R])
HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL])
+ HAVE_STRLCPY=1; AC_SUBST([HAVE_STRLCPY])
HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP])
REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR])
REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM])
REPLACE_STPNCPY=0; AC_SUBST([REPLACE_STPNCPY])
+ REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL])
REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP])
+ REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT])
+ REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP])
+ REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN])
REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR])
REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR])
- REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL])
+ REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R])
REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR])
REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R])
- REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT])
- REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP])
- REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN])
REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL])
- REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R])
+ REPLACE_STRLCPY=0; AC_SUBST([REPLACE_STRLCPY])
UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R])
])
diff --git a/m4/strlcpy.m4 b/m4/strlcpy.m4
new file mode 100644
index 0000000..68eaf48
--- /dev/null
+++ b/m4/strlcpy.m4
@@ -0,0 +1,22 @@
+# strlcpy.m4 serial 1
+dnl Copyright (C) 2017 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STRLCPY],
+[
+ AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+
+ AC_CHECK_FUNCS_ONCE([strlcpy])
+ if test $ac_cv_func_strlcpy = yes; then
+ dnl The system's declares the function without
+ dnl __attribute__((__warn_unused_result__)). Therefore override it.
+ REPLACE_STRLCPY=1
+ else
+ HAVE_STRLCPY=0
+ fi
+])
+
+# Prerequisites of lib/strlcpy.c.
+AC_DEFUN([gl_PREREQ_STRLCPY], [:])
diff --git a/modules/string b/modules/string
index 8a07da5..daa079b 100644
--- a/modules/string
+++ b/modules/string
@@ -67,6 +67,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
-e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
-e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \
+ -e 's/@''GNULIB_STRLCPY''@/$(GNULIB_STRLCPY)/g' \
-e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
< $(srcdir)/string.in.h | \
sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \
@@ -90,21 +91,23 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \
-e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \
-e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
+ -e 's|@''HAVE_STRLCPY''@|$(HAVE_STRLCPY)|g' \
-e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \
- -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
-e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
-e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
- -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \
+ -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
-e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \
-e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \
- -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
- -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
- -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \
-e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \
-e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \
-e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \
- -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
+ -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
+ -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \
-e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \
+ -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
+ -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \
+ -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
+ -e 's|@''REPLACE_STRLCPY''@|$(REPLACE_STRLCPY)|g' \
-e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
diff --git a/modules/strlcpy b/modules/strlcpy
new file mode 100644
index 0000000..f12d8d6
--- /dev/null
+++ b/modules/strlcpy
@@ -0,0 +1,26 @@
+Description:
+strlcpy() function: copy a string into a bounded memory area.
+
+Files:
+lib/strlcpy.c
+m4/strlcpy.m4
+
+Depends-on:
+string
+
+configure.ac:
+gl_FUNC_STRLCPY
+gl_PREREQ_STRLCPY
+gl_STRING_MODULE_INDICATOR([strlcpy])
+
+Makefile.am:
+lib_SOURCES += strlcpy.c
+
+Include:
+
+
+License:
+LGPLv2+
+
+Maintainer:
+all
--
2.7.4