diff options
author | Matthias Andree <matthias.andree@gmx.de> | 2020-05-04 03:04:59 +0200 |
---|---|---|
committer | Matthias Andree <matthias.andree@gmx.de> | 2020-05-04 03:04:59 +0200 |
commit | 11ba27271f8e085b06c79b732cf92f88e492f487 (patch) | |
tree | 01e60e8b46051143ee60b8cc34fce507a4078f08 /fm_realpath.c | |
parent | faaeaa43e1978fe3d24d7289487021664397cdbe (diff) | |
download | fetchmail-11ba27271f8e085b06c79b732cf92f88e492f487.tar.gz fetchmail-11ba27271f8e085b06c79b732cf92f88e492f487.tar.bz2 fetchmail-11ba27271f8e085b06c79b732cf92f88e492f487.zip |
Add fm_realpath(): a malloc()ating realpath() wrapper.
Diffstat (limited to 'fm_realpath.c')
-rw-r--r-- | fm_realpath.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/fm_realpath.c b/fm_realpath.c new file mode 100644 index 00000000..5ae8ca08 --- /dev/null +++ b/fm_realpath.c @@ -0,0 +1,62 @@ +#include "config.h" +#include "fetchmail.h" +#include "i18n.h" + +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +/* similar to realpath(file_name, NULL) - on systems that do not natively + * support the resolved file name to be passed as NULL, malloc() the buffer of + * PATH_MAX + 1 bytes, or abort if the system does not define PATH_MAX + */ +char *fm_realpath(const char *restrict file_name) +{ + char *rv; + + if (NULL == file_name) { + errno = EINVAL; + return NULL; + } + + rv = realpath(file_name, NULL); + /* FreeBSD, recent GNU libc, and all SUSv4 + * compliant systems auto-allocate => done */ + if (NULL == rv && errno == EINVAL) { + /* Implementation does not auto-allocate, but + * PATH_MAX is provided (Solaris 10, f.i.) */ +#if HAVE_DECL_PATH_MAX + char *b = (char *)xmalloc(PATH_MAX + 1); + rv = realpath(file_name, b); +#else + /* unsupported */ + report(stderr, GT_("Your operating system neither defines PATH_MAX nor will it accept realpath(f, NULL). Aborting.\n")); + abort(); +#endif + } + return rv; +} + +#ifdef TEST +#include <string.h> +const char *program_name= __FILE__; + +int main(int argc, char **argv) +{ + int i; + int e = EXIT_SUCCESS; + for (i = 1; i < argc; ++i) { + char *p = fm_realpath(argv[i]); + if (p) { + printf("%s -> %s\n", argv[i], p); + free(p); + } else { + fprintf(stderr, "%s: error: %s\n", argv[i], strerror(errno)); + e = EXIT_FAILURE; + } + } + exit(e); +} +#endif |