diff options
| author | Georgi Chorbadzhiyski <gf@unixsol.org> | 2012-03-16 06:42:08 -0500 | 
|---|---|---|
| committer | Georgi Chorbadzhiyski <gf@unixsol.org> | 2012-03-16 06:42:08 -0500 | 
| commit | 522d90613ae7dc728a98d3ce3b939b4ad9b30f25 (patch) | |
| tree | 3aa0a983f34e0d9c427bc012c532c324fbafdf15 | |
| parent | c4849f7e354d3c685c44ac2b2a7110238b17122b (diff) | |
| download | toybox-522d90613ae7dc728a98d3ce3b939b4ad9b30f25.tar.gz | |
Implement Apple and Android versions of getline(), getdelim(), and clearenv().
| -rw-r--r-- | lib/portability.c | 75 | ||||
| -rw-r--r-- | lib/portability.h | 8 | 
2 files changed, 82 insertions, 1 deletions
| diff --git a/lib/portability.c b/lib/portability.c new file mode 100644 index 00000000..b1c448c8 --- /dev/null +++ b/lib/portability.c @@ -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 diff --git a/lib/portability.h b/lib/portability.h index 0887d873..832dd123 100644 --- a/lib/portability.h +++ b/lib/portability.h @@ -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 | 
