From 933e986a9207d2b61c5119e18603b44b924e7226 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Thu, 7 Dec 2017 15:49:02 +0000 Subject: Finally implement sarealpath() over realpath(). Prettier atomic_symlink(). --- src/libstddjb/absolutepath.c | 12 -------- src/libstddjb/absolutepath_tmp.c | 63 -------------------------------------- src/libstddjb/sarealpath.c | 26 ++++++++++++++++ src/libstddjb/sarealpath_tmp.c | 11 +++++++ src/libunixonacid/atomic_symlink.c | 13 ++++++-- 5 files changed, 47 insertions(+), 78 deletions(-) delete mode 100644 src/libstddjb/absolutepath.c delete mode 100644 src/libstddjb/absolutepath_tmp.c create mode 100644 src/libstddjb/sarealpath.c create mode 100644 src/libstddjb/sarealpath_tmp.c (limited to 'src') diff --git a/src/libstddjb/absolutepath.c b/src/libstddjb/absolutepath.c deleted file mode 100644 index 9a7a19f..0000000 --- a/src/libstddjb/absolutepath.c +++ /dev/null @@ -1,12 +0,0 @@ -/* ISC license. */ - -/* MT-unsafe */ - -#include -#include -#include - -int sarealpath (stralloc *sa, char const *path) -{ - return sarealpath_tmp(sa, path, &satmp) ; -} diff --git a/src/libstddjb/absolutepath_tmp.c b/src/libstddjb/absolutepath_tmp.c deleted file mode 100644 index 100a7e9..0000000 --- a/src/libstddjb/absolutepath_tmp.c +++ /dev/null @@ -1,63 +0,0 @@ -/* ISC license. */ - -/* MT-unsafe (because of chdir) */ - -#include -#include -#include -#include - -int sarealpath_tmp (stralloc *sa, char const *path, stralloc *tmp) -{ - size_t tmpbase = tmp->len ; - size_t base = sa->len ; - unsigned int loop = 48 ; - int fdhere ; - int wasnull = !sa->s ; - - if (!path) return (errno = EINVAL, -1) ; - if (!stralloc_cats(sa, path)) return -1 ; - fdhere = open_read(".") ; - if (fdhere == -1) - { - if (wasnull) stralloc_free(sa) ; else sa->len = base ; - return -1 ; - } - - do - { - tmp->len = tmpbase ; - if (!loop--) { errno = ELOOP ; goto err ; } - if (!sadirname(tmp, sa->s + base, sa->len - base) - || !stralloc_0(tmp) - || (chdir(tmp->s + tmpbase) == -1)) - goto err ; - tmp->len = tmpbase ; - if (!sabasename(tmp, sa->s + base, sa->len - base) - || !stralloc_0(tmp)) goto err ; - sa->len = base ; - } - while (sareadlink(sa, tmp->s + tmpbase) >= 0) ; - - if ((errno != EINVAL) - || (sagetcwd(sa) == -1) - || ((sa->len > base + 1) && !stralloc_catb(sa, "/", 1)) - || ((--tmp->len > tmpbase) && (tmp->s[tmpbase] != '/') && !stralloc_catb(sa, tmp->s + tmpbase, tmp->len - tmpbase))) - goto err ; - - tmp->len = tmpbase ; - fd_chdir(fdhere) ; - fd_close(fdhere) ; - return 0 ; - -err: - { - int e = errno ; - tmp->len = tmpbase ; - fd_chdir(fdhere) ; - fd_close(fdhere) ; - if (wasnull) stralloc_free(sa) ; else sa->len = base ; - errno = e ; - } - return -1 ; -} diff --git a/src/libstddjb/sarealpath.c b/src/libstddjb/sarealpath.c new file mode 100644 index 0000000..0cf1825 --- /dev/null +++ b/src/libstddjb/sarealpath.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include + +int sarealpath (stralloc *sa, char const *path) +{ + if (sa->s) + { + if (!stralloc_readyplus(sa, PATH_MAX)) return -1 ; + if (!realpath(path, sa->s + sa->len)) return -1 ; + sa->len += strlen(sa->s + sa->len) ; + } + else + { + char *p = realpath(path, 0) ; + if (!p) return -1 ; + sa->s = p ; + sa->len = strlen(p) ; + sa->a = sa->len + 1 ; + } + return 0 ; +} diff --git a/src/libstddjb/sarealpath_tmp.c b/src/libstddjb/sarealpath_tmp.c new file mode 100644 index 0000000..31aeeb2 --- /dev/null +++ b/src/libstddjb/sarealpath_tmp.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +/* This function is now obsolete. */ + +#include + +int sarealpath_tmp (stralloc *sa, char const *path, stralloc *tmp) +{ + (void)tmp ; + return sarealpath(sa, path) ; +} diff --git a/src/libunixonacid/atomic_symlink.c b/src/libunixonacid/atomic_symlink.c index 660e4d3..d438263 100644 --- a/src/libunixonacid/atomic_symlink.c +++ b/src/libunixonacid/atomic_symlink.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -17,7 +18,7 @@ int atomic_symlink (char const *target, char const *name, char const *suffix) } { size_t namelen = strlen(name) ; - size_t suffixlen = suffix ? strlen(suffix) : 8 ; + size_t suffixlen = suffix ? strlen(suffix) : 25 ; char tmp[namelen + suffixlen + 2] ; memcpy(tmp, name, namelen) ; tmp[namelen] = ':' ; @@ -25,8 +26,14 @@ int atomic_symlink (char const *target, char const *name, char const *suffix) memcpy(tmp + namelen + 1, suffix, suffixlen + 1) ; else { - random_name(tmp + namelen + 1, 8) ; - tmp[namelen + 9] = 0 ; + memcpy(tmp + namelen + 1, "atomic_symlink:", 15) ; + random_name(tmp + namelen + 16, 8) ; + tmp[namelen + 24] = 0 ; + } + { + int e = errno ; + if (unlink(tmp) < 0 && errno != ENOENT) return 0 ; + errno = e ; } if (symlink(target, tmp) < 0) return 0 ; if (rename(tmp, name) < 0) -- cgit v1.2.3