Implement xstrncat() and fix xstrndup().
authorRob Landley <rob@landley.net>
Fri, 5 Dec 2014 03:41:12 +0000 (21:41 -0600)
committerRob Landley <rob@landley.net>
Fri, 5 Dec 2014 03:41:12 +0000 (21:41 -0600)
lib/lib.h
lib/xwrap.c

index 49b02bb..0755539 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -81,6 +81,7 @@ void show_help(void);
 
 // xwrap.c
 void xstrncpy(char *dest, char *src, size_t size);
+void xstrncat(char *dest, char *src, size_t size);
 void xexit(void) noreturn;
 void *xmalloc(size_t size);
 void *xzalloc(size_t size);
index a2dd1c6..96db352 100644 (file)
@@ -9,13 +9,25 @@
 
 #include "toys.h"
 
-// Strcpy with size checking: exit if there's not enough space for the string.
+// strcpy and strncat with size checking. Size is the total space in "dest",
+// including null terminator. Exit if there's not enough space for the string
+// (including space for the null terminator), because silently truncating is
+// still broken behavior. (And leaving the string unterminated is INSANE.)
 void xstrncpy(char *dest, char *src, size_t size)
 {
   if (strlen(src)+1 > size) error_exit("'%s' > %ld bytes", src, (long)size);
   strcpy(dest, src);
 }
 
+void xstrncat(char *dest, char *src, size_t size)
+{
+  long len = strlen(src);
+
+  if (len+strlen(dest)+1 > size)
+    error_exit("'%s%s' > %ld bytes", src, (long)size);
+  strcpy(dest+len, src);
+}
+
 void xexit(void)
 {
   if (toys.rebound) longjmp(*toys.rebound, 1);
@@ -52,9 +64,10 @@ void *xrealloc(void *ptr, size_t size)
 // Die unless we can allocate a copy of this many bytes of string.
 char *xstrndup(char *s, size_t n)
 {
-  char *ret = xmalloc(++n);
-  strncpy(ret, s, n);
-  ret[--n]=0;
+  char *ret = strndup(s, ++n);
+
+  if (!ret) error_exit("xstrndup");
+  ret[--n] = 0;
 
   return ret;
 }