diff options
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | efreadlink.c | 18 | ||||
-rw-r--r-- | enfreadlink.c | 18 | ||||
-rw-r--r-- | enreadlink.c | 18 | ||||
-rw-r--r-- | enreadlinkat.c | 29 | ||||
-rw-r--r-- | enreadmagiclink.c | 25 | ||||
-rw-r--r-- | ereadlink.c | 18 | ||||
-rw-r--r-- | ereadlinkat.c | 18 | ||||
-rw-r--r-- | ereadmagiclink.c | 18 | ||||
-rw-r--r-- | freadlink.c | 18 | ||||
-rw-r--r-- | libsimple/path.h | 71 | ||||
-rw-r--r-- | readlink.c | 18 | ||||
-rw-r--r-- | readlinkat.c | 41 | ||||
-rw-r--r-- | readmagiclink.c | 61 |
14 files changed, 383 insertions, 0 deletions
@@ -411,6 +411,7 @@ OBJ =\ ealigned_wmemdup.o\ ecalloc.o\ ecallocn.o\ + efreadlink.o\ egetcwd.o\ egmtime.o\ elocaltime.o\ @@ -440,6 +441,7 @@ OBJ =\ enaligned_wmemdup.o\ encalloc.o\ encallocn.o\ + enfreadlink.o\ engetcwd.o\ engmtime.o\ enlocaltime.o\ @@ -463,6 +465,9 @@ OBJ =\ enpvallocn.o\ enpvallocz.o\ enpvalloczn.o\ + enreadlink.o\ + enreadlinkat.o\ + enreadmagiclink.o\ enrealloc.o\ enreallocarray.o\ enreallocn.o\ @@ -502,6 +507,9 @@ OBJ =\ epvallocn.o\ epvallocz.o\ epvalloczn.o\ + ereadlink.o\ + ereadlinkat.o\ + ereadmagiclink.o\ erealloc.o\ ereallocarray.o\ ereallocn.o\ @@ -540,6 +548,7 @@ OBJ =\ fexecl.o\ fexecle.o\ fexecv.o\ + freadlink.o\ generate_seed.o\ getcwd.o\ getenv_e.o\ @@ -943,6 +952,9 @@ OBJ =\ rawmemrchr_inv.o\ rawmemrelem.o\ rawmemrelem_inv.o\ + readlink.o\ + readlinkat.o\ + readmagiclink.o\ reallocarray.o\ reallocarrayf.o\ reallocf.o\ diff --git a/efreadlink.c b/efreadlink.c new file mode 100644 index 0000000..a76c411 --- /dev/null +++ b/efreadlink.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_efreadlink(int); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/enfreadlink.c b/enfreadlink.c new file mode 100644 index 0000000..9f6a055 --- /dev/null +++ b/enfreadlink.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_enfreadlink(int, int); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/enreadlink.c b/enreadlink.c new file mode 100644 index 0000000..669e1fd --- /dev/null +++ b/enreadlink.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_enreadlink(int, const char *); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/enreadlinkat.c b/enreadlinkat.c new file mode 100644 index 0000000..74b4562 --- /dev/null +++ b/enreadlinkat.c @@ -0,0 +1,29 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +char * +libsimple_enreadlinkat(int status, int dirfd, const char *path) +{ + char *ret = libsimple_readlinkat(dirfd, path); + if (!ret) { + if (dirfd == AT_FDCWD) + libsimple_enprintf(status, "libsimple_readlinkat AT_FDCWD %s:", path); + else + libsimple_enprintf(status, "libsimple_readlinkat %i %s:", dirfd, path); + } + return ret; +} + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/enreadmagiclink.c b/enreadmagiclink.c new file mode 100644 index 0000000..a4a99a4 --- /dev/null +++ b/enreadmagiclink.c @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +char * +libsimple_enreadmagiclink(int status, const char *path) +{ + char *ret = libsimple_readmagiclink(path); + if (!ret) + libsimple_enprintf(status, "libsimple_readmagiclinkat %s:", path); + return ret; +} + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/ereadlink.c b/ereadlink.c new file mode 100644 index 0000000..3b990e4 --- /dev/null +++ b/ereadlink.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_ereadlink(const char *); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/ereadlinkat.c b/ereadlinkat.c new file mode 100644 index 0000000..7294ade --- /dev/null +++ b/ereadlinkat.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_ereadlinkat(int, const char *); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/ereadmagiclink.c b/ereadmagiclink.c new file mode 100644 index 0000000..396e618 --- /dev/null +++ b/ereadmagiclink.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_ereadmagiclink(const char *); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/freadlink.c b/freadlink.c new file mode 100644 index 0000000..90f5380 --- /dev/null +++ b/freadlink.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_freadlink(int); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/libsimple/path.h b/libsimple/path.h index 65f2751..6f2a8b8 100644 --- a/libsimple/path.h +++ b/libsimple/path.h @@ -68,3 +68,74 @@ libsimple_eabspath(const char *p__, const char *r__) /* TODO man */ { return libsimple_enabspath(libsimple_default_failure_exit, p__, r__); } + + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__))) +char *libsimple_readlinkat(int, const char *); /* TODO man, doc */ + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +char *libsimple_enreadlinkat(int, int, const char *); /* TODO man, doc */ + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +inline char * +libsimple_ereadlinkat(int dirfd__, const char *path__) /* TODO man, doc */ +{ + return libsimple_enreadlinkat(libsimple_default_failure_exit, dirfd__, path__); +} + + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__))) +inline char * +libsimple_readlink(const char *path__) /* TODO man, doc */ +{ + return libsimple_readlinkat(AT_FDCWD, path__); +} + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +inline char * +libsimple_enreadlink(int status__, const char *path__) /* TODO man, doc */ +{ + return libsimple_enreadlinkat(status__, AT_FDCWD, path__); +} + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +inline char * +libsimple_ereadlink(const char *path__) /* TODO man, doc */ +{ + return libsimple_enreadlinkat(libsimple_default_failure_exit, AT_FDCWD, path__); +} + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__))) +inline char * +libsimple_freadlink(int fd__) /* TODO man, doc */ +{ + return libsimple_readlinkat(fd__, ""); +} + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +inline char * +libsimple_enfreadlink(int status__, int fd__) /* TODO man, doc */ +{ + return libsimple_enreadlinkat(status__, fd__, ""); +} + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +inline char * +libsimple_efreadlink(int fd__) /* TODO man, doc */ +{ + return libsimple_enreadlinkat(libsimple_default_failure_exit, fd__, ""); +} + + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__))) +char *libsimple_readmagiclink(const char *); /* TODO man, doc */ + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +char *libsimple_enreadmagiclink(int, const char *); /* TODO man, doc */ + +LIBSIMPLE_GCC_ONLY__(__attribute__((__malloc__, __assume_aligned__(1), __warn_unused_result__, __nonnull__, __returns_nonnull__))) +inline char * +libsimple_ereadmagiclink(const char *path__) /* TODO man, doc */ +{ + return libsimple_enreadmagiclink(libsimple_default_failure_exit, path__); +} diff --git a/readlink.c b/readlink.c new file mode 100644 index 0000000..2bd9ffb --- /dev/null +++ b/readlink.c @@ -0,0 +1,18 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +extern inline char *libsimple_readlink(const char *); + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/readlinkat.c b/readlinkat.c new file mode 100644 index 0000000..2ec5e88 --- /dev/null +++ b/readlinkat.c @@ -0,0 +1,41 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +char * +libsimple_readlinkat(int dirfd, const char *path) +{ + char *ret = NULL, *new; + size_t size = 0; + ssize_t r; + + do { + new = realloc(ret, size += 128); + if (!new) { + errno = ENOMEM; + fail: + free(ret); + return NULL; + } + ret = new; + r = readlinkat(dirfd, path, ret, size - 1U); + if (r < 0) + goto fail; + } while ((size_t)r >= size - 2U); + + ret[r] = '\0'; + return ret; +} + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif diff --git a/readmagiclink.c b/readmagiclink.c new file mode 100644 index 0000000..160dd96 --- /dev/null +++ b/readmagiclink.c @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +char * +libsimple_readmagiclink(const char *path) +{ + int fd; + struct stat st; + char *target1; + char *target2; + + fd = open(path, O_PATH | O_NOFOLLOW); + if (fd < 0) + return NULL; + + target1 = libsimple_efreadlink(fd); + if (!strends(target1, " (deleted)")) { + close(fd); + return target1; + } + + if (fstat(fd, &st)) { + free(target1); + close(fd); + return NULL; + } + + target2 = libsimple_efreadlink(fd); + if (!strends(target2, " (deleted)")) { + free(target1); + close(fd); + return target2; + } + + close(fd); + + if (strcmp(target1, target2)) { + free(target2); + return target1; + } else { + free(target1); + if (st.st_nlink) + return target2; + target2[strlen(target2) - (sizeof(" (deleted)") - 1U)] = '\0'; + return target2; + } +} + + +#else +#include "test.h" + +int +main(void) /* TODO test */ +{ + return 0; +} + +#endif |