[notmuch] [PATCH] Mac OS X compatibility fixes

Jjgod Jiang gzjjgod at gmail.com
Sat Nov 21 19:07:36 PST 2009


Add missing GNU extensions strdup() and getline(). The C library
shipped with Mac OS X does not include them (though it does support
some GNU extensions when _GNU_SOURCE is defined), so we have to
add these two. The getline() implementation is a modified version
of getdelim() from GNU Libc.
---
 lib/xutil.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/xutil.h |    6 +++
 2 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/lib/xutil.c b/lib/xutil.c
index 6fa5eb0..805b236 100644
--- a/lib/xutil.c
+++ b/lib/xutil.c
@@ -79,6 +79,105 @@ xstrdup (const char *s)
     return ret;
 }
 
+#ifdef __APPLE__
+/* Mac OS X don't have strndup even if _GNU_SOURCE is defined */
+char *strndup (const char *s, size_t n)
+{
+    size_t len = strlen (s);
+    char *ret;
+
+    if (len <= n)
+	return strdup (s);
+
+    ret = malloc(n + 1);
+    strncpy(ret, s, n);
+    ret[n] = '\0';
+    return ret;
+}
+
+/* getline implementation is copied from glibc. */
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+ssize_t getline (char **lineptr, size_t *n, FILE *fp)
+{
+    ssize_t result;
+    size_t cur_len = 0;
+
+    if (lineptr == NULL || n == NULL || fp == NULL)
+    {
+	errno = EINVAL;
+	return -1;
+    }
+
+    if (*lineptr == NULL || *n == 0)
+    {
+	*n = 120;
+	*lineptr = (char *) malloc (*n);
+	if (*lineptr == NULL)
+	{
+	    result = -1;
+	    goto end;
+	}
+    }
+
+    for (;;)
+    {
+	int i;
+
+	i = getc (fp);
+	if (i == EOF)
+	{
+	    result = -1;
+	    break;
+	}
+
+	/* Make enough space for len+1 (for final NUL) bytes.  */
+	if (cur_len + 1 >= *n)
+	{
+	    size_t needed_max =
+		SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+	    size_t needed = 2 * *n + 1;   /* Be generous. */
+	    char *new_lineptr;
+
+	    if (needed_max < needed)
+		needed = needed_max;
+	    if (cur_len + 1 >= needed)
+	    {
+		result = -1;
+		goto end;
+	    }
+
+	    new_lineptr = (char *) realloc (*lineptr, needed);
+	    if (new_lineptr == NULL)
+	    {
+		result = -1;
+		goto end;
+	    }
+
+	    *lineptr = new_lineptr;
+	    *n = needed;
+	}
+
+	(*lineptr)[cur_len] = i;
+	cur_len++;
+
+	if (i == '\n')
+	    break;
+    }
+    (*lineptr)[cur_len] = '\0';
+    result = cur_len ? (ssize_t) cur_len : result;
+
+end:
+    return result;
+}
+#endif
+
 char *
 xstrndup (const char *s, size_t n)
 {
diff --git a/lib/xutil.h b/lib/xutil.h
index b973f7d..0b53f7c 100644
--- a/lib/xutil.h
+++ b/lib/xutil.h
@@ -25,6 +25,12 @@
 #include <sys/types.h>
 #include <regex.h>
 
+#ifdef __APPLE__
+/* Mac OS X don't have strndup and getline even if _GNU_SOURCE is defined */
+char *strndup (const char *s, size_t n);
+ssize_t getline(char **lineptr, size_t *n, FILE *stream);
+#endif
+
 /* xutil.c */
 void *
 xcalloc (size_t nmemb, size_t size);
-- 
1.6.4



More information about the notmuch mailing list