diff options
author | A. Wilcox <awilcox@wilcox-tech.com> | 2018-09-21 21:30:18 +0000 |
---|---|---|
committer | A. Wilcox <awilcox@wilcox-tech.com> | 2018-09-21 21:30:18 +0000 |
commit | e7fd895295db6291319af09ffaa3b6d93180788c (patch) | |
tree | 6ad80501db199c916e8fc2ed5648bf694a257675 /libgcompat/realpath.c | |
parent | 938c8095e7456fbcdf4ce261bdb6dfa3a8e41b80 (diff) | |
parent | 9bc7c737b311fcbba71af11884b7f9111dba57ba (diff) | |
download | gcompat-e7fd895295db6291319af09ffaa3b6d93180788c.tar.gz gcompat-e7fd895295db6291319af09ffaa3b6d93180788c.tar.bz2 gcompat-e7fd895295db6291319af09ffaa3b6d93180788c.tar.xz gcompat-e7fd895295db6291319af09ffaa3b6d93180788c.zip |
Merge branch 'patch-3' into 'master'
Add some more functions (notably __cxa_thread_atexit_impl and realpath) and run clang-format
See merge request !3
Diffstat (limited to 'libgcompat/realpath.c')
-rw-r--r-- | libgcompat/realpath.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/libgcompat/realpath.c b/libgcompat/realpath.c new file mode 100644 index 0000000..ab68cc4 --- /dev/null +++ b/libgcompat/realpath.c @@ -0,0 +1,51 @@ +#include <dlfcn.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifndef LINKER +#error LINKER must be defined +#endif + +static char *(*real_realpath)(const char *restrict, char *restrict); + +char *realpath(const char *restrict path, char *restrict resolved) +{ + if (real_realpath == NULL) { + real_realpath = dlsym(RTLD_NEXT, "realpath"); + if (real_realpath == NULL) { + errno = ENOSYS; + return NULL; + } + } + + if (!strcmp(path, "/proc/self/exe")) { + char *fixed = resolved; + + if (fixed == NULL) { + fixed = malloc(PATH_MAX); + if (fixed == NULL) { + errno = ENOMEM; + return NULL; + } + } + + /* If passed in, the buffer is at least PATH_MAX per POSIX. */ + ssize_t written = readlink(path, fixed, PATH_MAX - 1); + if (written == -1) { + /* Free the buffer iff we allocated it. */ + if (fixed != resolved) + free(fixed); + return NULL; + } + fixed[written] = '\0'; + + return fixed; + } + + return real_realpath(path, resolved); +} |