From 11f210ecaa0e085612058b459523fa2003578aa5 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Sun, 3 Dec 2017 20:09:22 +0000 Subject: Add atomic_symlink(), prepare for 2.6.3.0 --- src/libunixonacid/atomic_symlink.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/libunixonacid/atomic_symlink.c (limited to 'src/libunixonacid') diff --git a/src/libunixonacid/atomic_symlink.c b/src/libunixonacid/atomic_symlink.c new file mode 100644 index 0000000..660e4d3 --- /dev/null +++ b/src/libunixonacid/atomic_symlink.c @@ -0,0 +1,41 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include +#include + +int atomic_symlink (char const *target, char const *name, char const *suffix) +{ + { + int e = errno ; + if (symlink(target, name) == 0) return 1 ; + if (errno != EEXIST) return 0 ; + errno = e ; + } + { + size_t namelen = strlen(name) ; + size_t suffixlen = suffix ? strlen(suffix) : 8 ; + char tmp[namelen + suffixlen + 2] ; + memcpy(tmp, name, namelen) ; + tmp[namelen] = ':' ; + if (suffix) + memcpy(tmp + namelen + 1, suffix, suffixlen + 1) ; + else + { + random_name(tmp + namelen + 1, 8) ; + tmp[namelen + 9] = 0 ; + } + if (symlink(target, tmp) < 0) return 0 ; + if (rename(tmp, name) < 0) + { + int e = errno ; + unlink(tmp) ; + errno = e ; + return 0 ; + } + } + return 1 ; +} -- cgit v1.2.3