Mercurial > hg > toybox
diff lib/portability.c @ 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 | |
children | 786841fdb1e0 |
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