diff --git a/lib/cmdline.c b/lib/cmdline.c index 56141d94..f43ae4d0 100644 --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -50,6 +50,100 @@ #include "treemerge.h" #include "utilities.h" +#if defined(__APPLE__) +#include +#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1070) +/* there is no getdelim */ +#if __STDC_VERSION__ >= 199901L +/* restrict is a keyword */ +#else +# define restrict +#endif + +#ifndef _POSIX_SOURCE +typedef long ssize_t; +#define SSIZE_MAX LONG_MAX +#endif + +ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter, + FILE *restrict stream); +ssize_t getline(char **restrict lineptr, size_t *restrict n, + FILE *restrict stream); + +#define _GETDELIM_GROWBY 128 /* amount to grow line buffer by */ +#define _GETDELIM_MINLEN 4 /* minimum line buffer size */ + +ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter, + FILE *restrict stream) +{ + char *buf, *pos; + int c; + ssize_t bytes; + + if (lineptr == NULL || n == NULL) { + errno = EINVAL; + return -1; + } + if (stream == NULL) { + errno = EBADF; + return -1; + } + + /* resize (or allocate) the line buffer if necessary */ + buf = *lineptr; + if (buf == NULL || *n < _GETDELIM_MINLEN) { + buf = realloc(*lineptr, _GETDELIM_GROWBY); + if (buf == NULL) { + /* ENOMEM */ + return -1; + } + *n = _GETDELIM_GROWBY; + *lineptr = buf; + } + + /* read characters until delimiter is found, end of file is reached, or an error occurs. */ + bytes = 0; + pos = buf; + while ((c = getc(stream)) != EOF) { + if (bytes + 1 >= SSIZE_MAX) { + errno = EOVERFLOW; + return -1; + } + bytes++; + if (bytes >= *n - 1) { + buf = realloc(*lineptr, *n + _GETDELIM_GROWBY); + if (buf == NULL) { + /* ENOMEM */ + return -1; + } + *n += _GETDELIM_GROWBY; + pos = buf + bytes - 1; + *lineptr = buf; + } + + *pos++ = (char) c; + if (c == delimiter) { + break; + } + } + + if (ferror(stream) || (feof(stream) && (bytes == 0))) { + /* EOF, or an error from getc(). */ + return -1; + } + + *pos = '\0'; + return bytes; +} + +ssize_t getline(char **restrict lineptr, size_t *restrict n, + FILE *restrict stream) +{ + return getdelim(lineptr, n, '\n', stream); +} +#endif +#endif + /* define paranoia levels */ static const RmDigestType RM_PARANOIA_LEVELS[] = {RM_DIGEST_METRO, RM_DIGEST_METRO256, diff --git a/lib/traverse.c b/lib/traverse.c index d3d69256..b9597549 100644 --- a/lib/traverse.c +++ b/lib/traverse.c @@ -41,6 +41,15 @@ #include "fts/fts.h" +#if defined(__APPLE__) +#include +#if (MAC_OS_X_VERSION_MAX_ALLOWED < 1070) +#define st_atim st_atimespec +#define st_ctim st_ctimespec +#define st_mtim st_mtimespec +#endif +#endif + ////////////////////// // TRAVERSE SESSION // //////////////////////