summaryrefslogtreecommitdiff
path: root/libgcompat/string.c
diff options
context:
space:
mode:
authorWilliam Pitcock <nenolod@dereferenced.org>2017-06-14 13:09:23 -0500
committerWilliam Pitcock <nenolod@dereferenced.org>2017-06-14 13:09:23 -0500
commitf67416822a54109bd9cfa0fd210d7d8f53412ced (patch)
tree7d3d14933f39ca160d706d1bec25ce541a188962 /libgcompat/string.c
parent2b58008b911d9dc8354b9001e22b594fa6456dd1 (diff)
downloadgcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.tar.gz
gcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.tar.bz2
gcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.tar.xz
gcompat-f67416822a54109bd9cfa0fd210d7d8f53412ced.zip
move all compatibility library stuff into libgcompat/
Diffstat (limited to 'libgcompat/string.c')
-rw-r--r--libgcompat/string.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/libgcompat/string.c b/libgcompat/string.c
new file mode 100644
index 0000000..9a1cb60
--- /dev/null
+++ b/libgcompat/string.c
@@ -0,0 +1,84 @@
+#include <assert.h> /* assert */
+#include <string.h> /* memcpy, strcpy, strncat, strndup */
+
+/* "Checked" memcpy */
+void *__memcpy_chk(void *dest, const void *src, size_t len, size_t destlen)
+{
+ assert(dest != NULL);
+ assert(src != NULL);
+ assert(len <= destlen);
+ if(src < dest)
+ {
+ assert(!(src + len >= dest));
+ } else {
+ assert(!(dest + len >= src));
+ }
+ return memcpy(dest, src, len);
+}
+
+/* "Checked" strncat */
+char *__strncat_chk(char *dest, const char *src, size_t n, size_t destlen)
+{
+ assert(dest != NULL);
+ assert(src != NULL);
+ assert(n <= destlen);
+
+ return strncat(dest, src, n);
+}
+
+/* "Checked" strcat */
+char *__strcat_chk(char *dest, const char *src, size_t destlen)
+{
+ return strncat(dest, src, destlen - 1);
+}
+
+/* "Checked" strncpy */
+char *__strncpy_chk(char *dest, const char *src, size_t n, size_t destlen)
+{
+ assert(dest != NULL);
+ assert(src != NULL);
+ assert(strlen(src) < destlen);
+
+ return strncpy(dest, src, n);
+}
+
+/* "Checked" strcpy */
+char *__strcpy_chk(char *dest, const char *src, size_t destlen)
+{
+ assert(dest != NULL);
+ assert(src != NULL);
+ assert(strlen(src) < destlen);
+
+ return strcpy(dest, src);
+}
+
+/* Literally a useless __ alias. */
+char *__strndup(const char *str, size_t count)
+{
+ return strndup(str, count);
+}
+
+/* The existance of this method, and the fact it is used in real code, gives
+ * me nightmares. */
+void *rawmemchr(const void *s, int c)
+{
+ const unsigned char *haystack = s;
+ unsigned char needle = (unsigned char)c;
+ while(*haystack++ != needle);
+ return (void *)haystack;
+}
+
+extern __typeof(rawmemchr) __rawmemchr __attribute__((weak, alias("rawmemchr")));
+
+/* Another useless __ alias */
+char *__strtok_r(char *str, const char *delim, char **saveptr)
+{
+ return strtok_r(str, delim, saveptr);
+}
+
+/* The "global" definition of strsep in glibc, used when architecture dependent
+ * assembler versions aren't good enough. */
+char *__strsep_g(char **stringp, const char *delim)
+{
+ return strsep(stringp, delim);
+}