atomic_symlink.c (903B)
1 /* ISC license. */ 2 3 #include <string.h> 4 #include <unistd.h> 5 #include <errno.h> 6 #include <stdio.h> 7 8 #include <skalibs/posixplz.h> 9 #include <skalibs/unix-transactional.h> 10 11 int atomic_symlink (char const *target, char const *name, char const *suffix) 12 { 13 { 14 int e = errno ; 15 if (symlink(target, name) == 0) return 1 ; 16 if (errno != EEXIST) return 0 ; 17 errno = e ; 18 } 19 { 20 size_t namelen = strlen(name) ; 21 size_t suffixlen = suffix ? strlen(suffix) + 1 : 0 ; 22 char tmp[namelen + suffixlen + 8] ; 23 memcpy(tmp, name, namelen) ; 24 if (suffix) 25 { 26 tmp[namelen] = ':' ; 27 memcpy(tmp + namelen + 1, suffix, suffixlen - 1) ; 28 } 29 memcpy(tmp + namelen + suffixlen, ":XXXXXX", 7) ; 30 tmp[namelen + suffixlen + 7] = 0 ; 31 if (mkltemp(target, tmp) == -1) return 0 ; 32 if (rename(tmp, name) < 0) 33 { 34 unlink_void(tmp) ; 35 return 0 ; 36 } 37 } 38 return 1 ; 39 }