Better handling of collision with AIX stpncpy() function.
authorBruno Haible <bruno@clisp.org>
Fri, 26 Sep 2003 15:25:30 +0000 (15:25 +0000)
committerBruno Haible <bruno@clisp.org>
Fri, 26 Sep 2003 15:25:30 +0000 (15:25 +0000)
lib/ChangeLog
lib/stpncpy.c
lib/stpncpy.h
m4/ChangeLog
m4/stpncpy.m4

index fb74cdb5757e663a9223d370d9b8a4eddd285b6b..987ae0a58d9b0a3c24738bc1b403094e613e72c0 100644 (file)
@@ -1,3 +1,9 @@
+2003-09-26  Bruno Haible  <bruno@clisp.org>
+
+       * stpncpy.h (gnu_stpncpy): New declaration.
+       (stpncpy): Define as alias for gnu_stpncpy.
+       * stpncpy.c [!_LIBC]: Define gnu_stpncpy, not stpncpy.
+
 2003-09-26  Paul Eggert  <eggert@twinsun.com>
 
        * error.c (SIZE_MAX) [!defined SIZE_MAX]: Define.
index c302e398d72fc0d407e709a72ac9bf302e715951..3f7473f946c80ca22541df32a836f86ea74dfda0 100644 (file)
 /* Specification.  */
 #include "stpncpy.h"
 
+#if !HAVE_STPNCPY
+
+#ifndef _LIBC
+/* We cannot generally use the name 'stpncpy' since AIX 4 defines an unusable
+   variant of the function but we cannot use it.  */
+# undef stpncpy
+# define stpncpy gnu_stpncpy
+#endif
+
 #ifndef weak_alias
 # define __stpncpy stpncpy
 #endif
 
-/* Copy no more than N characters of SRC to DEST, returning the address of
-   the terminating '\0' in DEST, if any, or else DEST + N.  */
+/* Copy no more than N bytes of SRC to DST, returning a pointer past the
+   last non-NUL byte written into DST.  */
 char *
 __stpncpy (char *dest, const char *src, size_t n)
 {
@@ -93,3 +102,5 @@ __stpncpy (char *dest, const char *src, size_t n)
 #ifdef weak_alias
 weak_alias (__stpncpy, stpncpy)
 #endif
+
+#endif
index a457ee9d94699030a7eb4eb56c321a78ac05956f..cf658eb0714e40c5cbaa87ed96847e6aeab3a9e6 100644 (file)
 #ifndef _STPNCPY_H
 #define _STPNCPY_H
 
-#if HAVE_STPNCPY
-
-/* Get stpncpy() declaration.  */
 #include <string.h>
 
-#else
-
-#include <stddef.h>
+#if !HAVE_STPNCPY
 
-/* Copy no more than N characters of SRC to DST, returning the address of
-   the last character written into DST.  */
-extern char *stpncpy (char *dst, const char *src, size_t n);
+/* Copy no more than N bytes of SRC to DST, returning a pointer past the
+   last non-NUL byte written into DST.  */
+/* When not using the GNU libc we use the stpncpy implementation we
+   provide here.  */
+extern char *gnu_stpncpy (char *dst, const char *src, size_t n);
+#define stpncpy(Dst, Src, N) gnu_stpncpy (Dst, Src, N)
 
 #endif
 
index f5c561e742bc2ef0f6a4833463a16f5aaa4e77d2..61b46fe8df638659336bce21a690beb54b889b77 100644 (file)
@@ -1,3 +1,7 @@
+2003-09-26  Bruno Haible  <bruno@clisp.org>
+
+       * stpncpy.m4: Add comments about the AIX stpncpy().
+
 2003-09-25  Simon Josefsson  <jas@extundo.com>
             Bruno Haible  <bruno@clisp.org>
 
index 768cced0270728269eb04510cdd5eca973a1eb8c..fc47e65ccc78d41b37bedcba3657a5c791b0a438 100644 (file)
@@ -11,6 +11,16 @@ AC_DEFUN([gl_FUNC_STPNCPY],
   dnl Persuade glibc <string.h> to declare stpncpy().
   AC_REQUIRE([AC_GNU_SOURCE])
 
+  dnl Both glibc and AIX (4.3.3, 5.1) have an stpncpy() function
+  dnl declared in <string.h>. Its side effects are the same as those
+  dnl of strncpy():
+  dnl      stpncpy (dest, src, n)
+  dnl overwrites dest[0..n-1], min(strlen(src),n) bytes coming from src,
+  dnl and the remaining bytes being NULs.  However, the return value is
+  dnl   in glibc:   dest + min(strlen(src),n)
+  dnl   in AIX:     dest + max(0,n-1)
+  dnl Only the glibc return value is useful in practice.
+
   AC_CACHE_CHECK([for working stpncpy], gl_cv_func_stpncpy, [
     AC_TRY_RUN([
 #include <stdlib.h>