Mark Wielaard 68a09e
--- valgrind/memcheck/mc_replace_strmem.c
Mark Wielaard 68a09e
+++ valgrind/memcheck/mc_replace_strmem.c
Mark Wielaard 68a09e
@@ -101,6 +101,7 @@
Mark Wielaard 68a09e
    20390 WCSCPY
Mark Wielaard 68a09e
    20400 WCSCHR
Mark Wielaard 68a09e
    20410 WCSRCHR
Mark Wielaard 68a09e
+   20420 STPNCPY
Mark Wielaard 68a09e
 */
Mark Wielaard 68a09e
 
Mark Wielaard 68a09e
 
Mark Wielaard 68a09e
@@ -983,6 +984,34 @@ static inline void my_exit ( int x )
Mark Wielaard 68a09e
 #endif
Mark Wielaard 68a09e
 
Mark Wielaard 68a09e
 
Mark Wielaard 68a09e
+/*---------------------- stpncpy ----------------------*/
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+#define STPNCPY(soname, fnname) \
Mark Wielaard 68a09e
+   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
Mark Wielaard 68a09e
+            ( char* dst, const char* src, SizeT n ); \
Mark Wielaard 68a09e
+   char* VG_REPLACE_FUNCTION_EZU(20420,soname,fnname) \
Mark Wielaard 68a09e
+            ( char* dst, const char* src, SizeT n ) \
Mark Wielaard 68a09e
+   { \
Mark Wielaard 68a09e
+      const Char* src_orig = src; \
Mark Wielaard 68a09e
+            Char* dst_str  = dst; \
Mark Wielaard 68a09e
+      SizeT m = 0; \
Mark Wielaard 68a09e
+      \
Mark Wielaard 68a09e
+      while (m   < n && *src) { m++; *dst++ = *src++; } \
Mark Wielaard 68a09e
+      /* Check for overlap after copying; all n bytes of dst are relevant, */ \
Mark Wielaard 68a09e
+      /* but only m+1 bytes of src if terminator was found */ \
Mark Wielaard 68a09e
+      if (is_overlap(dst_str, src_orig, n, (m < n) ? m+1 : n)) \
Mark Wielaard 68a09e
+         RECORD_OVERLAP_ERROR("stpncpy", dst, src, n); \
Mark Wielaard 68a09e
+      dst_str = dst; \
Mark Wielaard 68a09e
+      while (m++ < n) *dst++ = 0;         /* must pad remainder with nulls */ \
Mark Wielaard 68a09e
+      \
Mark Wielaard 68a09e
+      return dst_str; \
Mark Wielaard 68a09e
+   }
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+#if defined(VGO_linux)
Mark Wielaard 68a09e
+ STPNCPY(VG_Z_LIBC_SONAME, stpncpy)
Mark Wielaard 68a09e
+#endif
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
 /*---------------------- memset ----------------------*/
Mark Wielaard 68a09e
 
Mark Wielaard 68a09e
 /* Why are we bothering to intercept this?  It seems entirely
Mark Wielaard 68a09e
--- valgrind/memcheck/tests/Makefile.am
Mark Wielaard 68a09e
+++ valgrind/memcheck/tests/Makefile.am
Mark Wielaard 68a09e
@@ -190,6 +190,7 @@ EXTRA_DIST = \
Mark Wielaard 68a09e
 	signal2.stderr.exp signal2.stdout.exp signal2.vgtest \
Mark Wielaard 68a09e
 	sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \
Mark Wielaard 68a09e
 	static_malloc.stderr.exp static_malloc.vgtest \
Mark Wielaard 68a09e
+	stpncpy.vgtest stpncpy.stderr.exp \
Mark Wielaard 68a09e
 	strchr.stderr.exp strchr.stderr.exp2 strchr.stderr.exp-darwin \
Mark Wielaard 68a09e
 	    strchr.stderr.exp3 strchr.vgtest \
Mark Wielaard 68a09e
 	str_tester.stderr.exp str_tester.vgtest \
Mark Wielaard 68a09e
@@ -286,6 +287,7 @@ check_PROGRAMS = \
Mark Wielaard 68a09e
 	sbfragment \
Mark Wielaard 68a09e
 	sh-mem sh-mem-random \
Mark Wielaard 68a09e
 	sigaltstack signal2 sigprocmask static_malloc sigkill \
Mark Wielaard 68a09e
+	stpncpy \
Mark Wielaard 68a09e
 	strchr \
Mark Wielaard 68a09e
 	str_tester \
Mark Wielaard 68a09e
 	supp_unknown supp1 supp2 suppfree \
Mark Wielaard 68a09e
--- /dev/null
Mark Wielaard 68a09e
+++ valgrind/memcheck/tests/stpncpy.c
Mark Wielaard 68a09e
@@ -0,0 +1,37 @@
Mark Wielaard 68a09e
+#include <stdio.h>
Mark Wielaard 68a09e
+#include <stdlib.h>
Mark Wielaard 68a09e
+#include <string.h>
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+int main(int argc, char **argv)
Mark Wielaard 68a09e
+{
Mark Wielaard 68a09e
+  char a[] = "The spazzy orange tiger jumped over the tawny jaguar.";
Mark Wielaard 68a09e
+  char *b, *c;
Mark Wielaard 68a09e
+  char *d, *e;
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+  size_t l = strlen (a);
Mark Wielaard 68a09e
+  fprintf (stderr, "strlen: %zd\n", l); // strlen: 53
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+  b = (char *) malloc((l + 3)); // Extra space for some zeros.
Mark Wielaard 68a09e
+  b[l] = 'X';
Mark Wielaard 68a09e
+  b[l + 1] = 'X';
Mark Wielaard 68a09e
+  b[l + 2] = 'X';
Mark Wielaard 68a09e
+  c = stpncpy (b, a, l + 3);
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+  fprintf (stderr, "equal: %d\n", strcmp (a, b)); // equal: 0
Mark Wielaard 68a09e
+  fprintf (stderr, "retlen: %zd\n", c - b); // retlen: 53
Mark Wielaard 68a09e
+  fprintf (stderr, "last: '%c'\n", *(c - 1)); // last: '.'
Mark Wielaard 68a09e
+  fprintf (stderr, "zero0: %d\n", *c); // zero0: 0
Mark Wielaard 68a09e
+  fprintf (stderr, "zero1: %d\n", *(c + 1)); // zero1: 0
Mark Wielaard 68a09e
+  fprintf (stderr, "zero2: %d\n", *(c + 2)); // zero2: 0
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+  d = (char *) malloc (l - 1); // No room for zero termination or dot.
Mark Wielaard 68a09e
+  e = stpncpy (d, b, l - 1);
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+  fprintf (stderr, "equal: %d\n", strncmp (b, d, l - 1)); // equal: 0
Mark Wielaard 68a09e
+  fprintf (stderr, "retlen: %zd\n", e - d); // retlen: 52
Mark Wielaard 68a09e
+  fprintf (stderr, "last: '%c'\n", *(e - 1)); // last: 'r'
Mark Wielaard 68a09e
+
Mark Wielaard 68a09e
+  free (b);
Mark Wielaard 68a09e
+  free (d);
Mark Wielaard 68a09e
+  return 0;
Mark Wielaard 68a09e
+}
Mark Wielaard 68a09e
--- /dev/null
Mark Wielaard 68a09e
+++ valgrind/memcheck/tests/stpncpy.stderr.exp
Mark Wielaard 68a09e
@@ -0,0 +1,10 @@
Mark Wielaard 68a09e
+strlen: 53
Mark Wielaard 68a09e
+equal: 0
Mark Wielaard 68a09e
+retlen: 53
Mark Wielaard 68a09e
+last: '.'
Mark Wielaard 68a09e
+zero0: 0
Mark Wielaard 68a09e
+zero1: 0
Mark Wielaard 68a09e
+zero2: 0
Mark Wielaard 68a09e
+equal: 0
Mark Wielaard 68a09e
+retlen: 52
Mark Wielaard 68a09e
+last: 'r'
Mark Wielaard 68a09e
--- /dev/null
Mark Wielaard 68a09e
+++ valgrind/memcheck/tests/stpncpy.vgtest
Mark Wielaard 68a09e
@@ -0,0 +1,2 @@
Mark Wielaard 68a09e
+prog: stpncpy
Mark Wielaard 68a09e
+vgopts: -q
Mark Wielaard 68a09e
--- valgrind/memcheck/tests/Makefile.in.orig	2012-11-04 21:02:22.477642451 +0100
Mark Wielaard 68a09e
+++ valgrind/memcheck/tests/Makefile.in	2012-11-04 21:04:10.077182544 +0100
Mark Wielaard 68a09e
@@ -108,16 +108,17 @@
Mark Wielaard 68a09e
 	realloc3$(EXEEXT) sbfragment$(EXEEXT) sh-mem$(EXEEXT) \
Mark Wielaard 68a09e
 	sh-mem-random$(EXEEXT) sigaltstack$(EXEEXT) signal2$(EXEEXT) \
Mark Wielaard 68a09e
 	sigprocmask$(EXEEXT) static_malloc$(EXEEXT) sigkill$(EXEEXT) \
Mark Wielaard 68a09e
-	strchr$(EXEEXT) str_tester$(EXEEXT) supp_unknown$(EXEEXT) \
Mark Wielaard 68a09e
-	supp1$(EXEEXT) supp2$(EXEEXT) suppfree$(EXEEXT) \
Mark Wielaard 68a09e
-	test-plo$(EXEEXT) trivialleak$(EXEEXT) unit_libcbase$(EXEEXT) \
Mark Wielaard 68a09e
-	unit_oset$(EXEEXT) varinfo1$(EXEEXT) varinfo2$(EXEEXT) \
Mark Wielaard 68a09e
-	varinfo3$(EXEEXT) varinfo4$(EXEEXT) varinfo5$(EXEEXT) \
Mark Wielaard 68a09e
-	varinfo5so.so$(EXEEXT) varinfo6$(EXEEXT) vcpu_fbench$(EXEEXT) \
Mark Wielaard 68a09e
-	vcpu_fnfns$(EXEEXT) wcs$(EXEEXT) xml1$(EXEEXT) wrap1$(EXEEXT) \
Mark Wielaard 68a09e
-	wrap2$(EXEEXT) wrap3$(EXEEXT) wrap4$(EXEEXT) wrap5$(EXEEXT) \
Mark Wielaard 68a09e
-	wrap6$(EXEEXT) wrap7$(EXEEXT) wrap7so.so$(EXEEXT) \
Mark Wielaard 68a09e
-	wrap8$(EXEEXT) writev1$(EXEEXT) $(am__EXEEXT_1)
Mark Wielaard 68a09e
+	stpncpy$(EXEEXT) strchr$(EXEEXT) str_tester$(EXEEXT) \
Mark Wielaard 68a09e
+	supp_unknown$(EXEEXT) supp1$(EXEEXT) supp2$(EXEEXT) \
Mark Wielaard 68a09e
+	suppfree$(EXEEXT) test-plo$(EXEEXT) trivialleak$(EXEEXT) \
Mark Wielaard 68a09e
+	unit_libcbase$(EXEEXT) unit_oset$(EXEEXT) varinfo1$(EXEEXT) \
Mark Wielaard 68a09e
+	varinfo2$(EXEEXT) varinfo3$(EXEEXT) varinfo4$(EXEEXT) \
Mark Wielaard 68a09e
+	varinfo5$(EXEEXT) varinfo5so.so$(EXEEXT) varinfo6$(EXEEXT) \
Mark Wielaard 68a09e
+	vcpu_fbench$(EXEEXT) vcpu_fnfns$(EXEEXT) wcs$(EXEEXT) \
Mark Wielaard 68a09e
+	xml1$(EXEEXT) wrap1$(EXEEXT) wrap2$(EXEEXT) wrap3$(EXEEXT) \
Mark Wielaard 68a09e
+	wrap4$(EXEEXT) wrap5$(EXEEXT) wrap6$(EXEEXT) wrap7$(EXEEXT) \
Mark Wielaard 68a09e
+	wrap7so.so$(EXEEXT) wrap8$(EXEEXT) writev1$(EXEEXT) \
Mark Wielaard 68a09e
+	$(am__EXEEXT_1)
Mark Wielaard 68a09e
 @DWARF4_TRUE@am__append_12 = dw4
Mark Wielaard 68a09e
 subdir = memcheck/tests
Mark Wielaard 68a09e
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
Mark Wielaard 68a09e
@@ -454,6 +455,9 @@
Mark Wielaard 68a09e
 static_malloc_SOURCES = static_malloc.c
Mark Wielaard 68a09e
 static_malloc_OBJECTS = static_malloc.$(OBJEXT)
Mark Wielaard 68a09e
 static_malloc_LDADD = $(LDADD)
Mark Wielaard 68a09e
+stpncpy_SOURCES = stpncpy.c
Mark Wielaard 68a09e
+stpncpy_OBJECTS = stpncpy.$(OBJEXT)
Mark Wielaard 68a09e
+stpncpy_LDADD = $(LDADD)
Mark Wielaard 68a09e
 str_tester_SOURCES = str_tester.c
Mark Wielaard 68a09e
 str_tester_OBJECTS = str_tester-str_tester.$(OBJEXT)
Mark Wielaard 68a09e
 str_tester_LDADD = $(LDADD)
Mark Wielaard 68a09e
@@ -608,7 +612,7 @@
Mark Wielaard 68a09e
 	pdb-realloc2.c pipe.c pointer-trace.c post-syscall.c \
Mark Wielaard 68a09e
 	realloc1.c realloc2.c realloc3.c sbfragment.c sh-mem.c \
Mark Wielaard 68a09e
 	sh-mem-random.c sigaltstack.c sigkill.c signal2.c \
Mark Wielaard 68a09e
-	sigprocmask.c static_malloc.c str_tester.c strchr.c \
Mark Wielaard 68a09e
+	sigprocmask.c static_malloc.c stpncpy.c str_tester.c strchr.c \
Mark Wielaard 68a09e
 	$(supp1_SOURCES) $(supp2_SOURCES) $(supp_unknown_SOURCES) \
Mark Wielaard 68a09e
 	suppfree.c test-plo.c trivialleak.c unit_libcbase.c \
Mark Wielaard 68a09e
 	unit_oset.c varinfo1.c varinfo2.c varinfo3.c varinfo4.c \
Mark Wielaard 68a09e
@@ -639,7 +643,7 @@
Mark Wielaard 68a09e
 	pdb-realloc2.c pipe.c pointer-trace.c post-syscall.c \
Mark Wielaard 68a09e
 	realloc1.c realloc2.c realloc3.c sbfragment.c sh-mem.c \
Mark Wielaard 68a09e
 	sh-mem-random.c sigaltstack.c sigkill.c signal2.c \
Mark Wielaard 68a09e
-	sigprocmask.c static_malloc.c str_tester.c strchr.c \
Mark Wielaard 68a09e
+	sigprocmask.c static_malloc.c stpncpy.c str_tester.c strchr.c \
Mark Wielaard 68a09e
 	$(supp1_SOURCES) $(supp2_SOURCES) $(supp_unknown_SOURCES) \
Mark Wielaard 68a09e
 	suppfree.c test-plo.c trivialleak.c unit_libcbase.c \
Mark Wielaard 68a09e
 	unit_oset.c varinfo1.c varinfo2.c varinfo3.c varinfo4.c \
Mark Wielaard 68a09e
@@ -1117,6 +1121,7 @@
Mark Wielaard 68a09e
 	signal2.stderr.exp signal2.stdout.exp signal2.vgtest \
Mark Wielaard 68a09e
 	sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \
Mark Wielaard 68a09e
 	static_malloc.stderr.exp static_malloc.vgtest \
Mark Wielaard 68a09e
+	stpncpy.vgtest stpncpy.stderr.exp \
Mark Wielaard 68a09e
 	strchr.stderr.exp strchr.stderr.exp2 strchr.stderr.exp-darwin \
Mark Wielaard 68a09e
 	    strchr.stderr.exp3 strchr.vgtest \
Mark Wielaard 68a09e
 	str_tester.stderr.exp str_tester.vgtest \
Mark Wielaard 68a09e
@@ -1576,6 +1581,9 @@
Mark Wielaard 68a09e
 static_malloc$(EXEEXT): $(static_malloc_OBJECTS) $(static_malloc_DEPENDENCIES) 
Mark Wielaard 68a09e
 	@rm -f static_malloc$(EXEEXT)
Mark Wielaard 68a09e
 	$(LINK) $(static_malloc_OBJECTS) $(static_malloc_LDADD) $(LIBS)
Mark Wielaard 68a09e
+stpncpy$(EXEEXT): $(stpncpy_OBJECTS) $(stpncpy_DEPENDENCIES) 
Mark Wielaard 68a09e
+	@rm -f stpncpy$(EXEEXT)
Mark Wielaard 68a09e
+	$(LINK) $(stpncpy_OBJECTS) $(stpncpy_LDADD) $(LIBS)
Mark Wielaard 68a09e
 str_tester$(EXEEXT): $(str_tester_OBJECTS) $(str_tester_DEPENDENCIES) 
Mark Wielaard 68a09e
 	@rm -f str_tester$(EXEEXT)
Mark Wielaard 68a09e
 	$(str_tester_LINK) $(str_tester_OBJECTS) $(str_tester_LDADD) $(LIBS)
Mark Wielaard 68a09e
@@ -1774,6 +1782,7 @@
Mark Wielaard 68a09e
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal2.Po@am__quote@
Mark Wielaard 68a09e
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigprocmask.Po@am__quote@
Mark Wielaard 68a09e
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/static_malloc.Po@am__quote@
Mark Wielaard 68a09e
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stpncpy.Po@am__quote@
Mark Wielaard 68a09e
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_tester-str_tester.Po@am__quote@
Mark Wielaard 68a09e
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strchr.Po@am__quote@
Mark Wielaard 68a09e
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/supp.Po@am__quote@