changeset 549:1f5bd8c93093

Implement Apple and Android versions of getline(), getdelim(), and clearenv().
author Georgi Chorbadzhiyski <gf@unixsol.org>
date Fri, 16 Mar 2012 06:42:08 -0500
parents 99cb6ad605ee
children b2194045c40e
files lib/portability.c lib/portability.h
diffstat 2 files changed, 82 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/portability.c	Fri Mar 16 06:42:08 2012 -0500
@@ -0,0 +1,75 @@
+/* vi: set sw=4 ts=4 :*/
+/* portability.c - code to workaround the deficiencies of various platforms.
+ *
+ * Copyright 2012 Rob Landley <rob@landley.net>
+ * Copyright 2012 Georgi Chorbadzhiyski <gf@unixsol.org>
+ */
+
+#include "toys.h"
+
+#if defined(__APPLE__) || defined(__ANDROID__)
+ssize_t getdelim(char **linep, size_t *np, int delim, FILE *stream)
+{
+	int ch;
+	size_t new_len;
+	ssize_t i = 0;
+	char *line, *new_line;
+
+	// Invalid input
+	if (!linep || !np) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (*linep == NULL || *np == 0) {
+		*np = 1024;
+		*linep = calloc(1, *np);
+		if (*linep == NULL)
+			return -1;
+	}
+	line = *linep;
+
+	while ((ch = getc(stream)) != EOF) {
+		if (i > *np) {
+			// Need more space
+			new_len  = *np + 1024;
+			new_line = realloc(*linep, new_len);
+			if (!new_line)
+				return -1;
+			*np    = new_len;
+			*linep = new_line;
+		}
+
+		line[i] = ch;
+		if (ch == delim)
+			break;
+		i += 1;
+	}
+
+	if (i > *np) {
+		// Need more space
+		new_len  = i + 2;
+		new_line = realloc(*linep, new_len);
+		if (!new_line)
+			return -1;
+		*np    = new_len;
+		*linep = new_line;
+	}
+	line[i + 1] = '\0';
+
+	return i > 0 ? i : -1;
+}
+
+ssize_t getline(char **linep, size_t *np, FILE *stream) {
+	return getdelim(linep, np, '\n', stream);
+}
+#endif
+
+#if defined(__APPLE__)
+extern char **environ;
+
+int clearenv(void) {
+	*environ = NULL;
+	return 0;
+}
+#endif
--- a/lib/portability.h	Fri Mar 16 06:20:48 2012 -0500
+++ b/lib/portability.h	Fri Mar 16 06:42:08 2012 -0500
@@ -1,5 +1,5 @@
 // The tendency of gcc to produce stupid warnings continues with
-// warn_unsed_result, which warns about things like ignoring the return code
+// warn_unused_result, which warns about things like ignoring the return code
 // of nice(2) (which is completely useless since -1 is a legitimate return
 // value on success and even the man page tells you to use errno instead).
 
@@ -33,6 +33,7 @@
 #define IS_BIG_ENDIAN 0
 #endif
 
+int clearenv(void);
 #else
 
 #ifdef __BIG_ENDIAN__
@@ -72,3 +73,8 @@
 #else
 #define GCC_BUG
 #endif
+
+#if defined(__APPLE__) || defined(__ANDROID__)
+ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);
+ssize_t getline(char **lineptr, size_t *n, FILE *stream);
+#endif