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 /lib/portability.c | |
parent | c4849f7e354d3c685c44ac2b2a7110238b17122b (diff) | |
download | toybox-522d90613ae7dc728a98d3ce3b939b4ad9b30f25.tar.gz |
Implement Apple and Android versions of getline(), getdelim(), and clearenv().
Diffstat (limited to 'lib/portability.c')
-rw-r--r-- | lib/portability.c | 75 |
1 files changed, 75 insertions, 0 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 |