aboutsummaryrefslogtreecommitdiffstats
path: root/src/libunixonacid/symlink_at.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2025-06-30 22:04:01 +0000
committerLaurent Bercot <ska@appnovation.com>2025-06-30 22:04:01 +0000
commit17cfa0cb58bcfadb08b355eb5fd511ed6829ee5d (patch)
treec543b313369bb13e5a6a894c0c1b1fb408ef4586 /src/libunixonacid/symlink_at.c
parentd4895d80b1b1af9086b08f7c6cb12f274baf2ddc (diff)
downloadskalibs-17cfa0cb58bcfadb08b355eb5fd511ed6829ee5d.tar.gz
Refactor _at functions, add symlink_at
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libunixonacid/symlink_at.c')
-rw-r--r--src/libunixonacid/symlink_at.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/libunixonacid/symlink_at.c b/src/libunixonacid/symlink_at.c
new file mode 100644
index 0000000..4d63120
--- /dev/null
+++ b/src/libunixonacid/symlink_at.c
@@ -0,0 +1,60 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+
+#ifdef SKALIBS_HASLINKAT
+
+#ifndef _ATFILE_SOURCE
+#define _ATFILE_SOURCE
+#endif
+
+#include <skalibs/nonposix.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <skalibs/fcntl.h>
+#include <skalibs/unix-transactional.h>
+
+int symlink_at (char const *src, int dirfd, char const *dst)
+{
+ int r ;
+ do r = symlinkat(src, dirfd, dst) ;
+ while (r == -1 && errno == EINTR) ;
+ return r ;
+}
+
+#else
+
+#include <unistd.h>
+#include <errno.h>
+
+#include <skalibs/posixplz.h>
+#include <skalibs/unix-transactional.h>
+
+struct symlink_s
+{
+ char const *src ;
+ char const *dst ;
+} ;
+
+static int do_symlink (void *p)
+{
+ struct symlink_s *b = p ;
+ return symlink(b->src, b->dst) ;
+}
+
+static void cancel_symlink (int r, void *p)
+{
+ struct symlink_s *b = p ;
+ (void)r ;
+ unlink_void(b->dst) ;
+}
+
+int symlink_at (char const *src, int dirfd, char const *dst)
+{
+ struct symlink_s args = { .src = src, .dst = dst } ;
+ return emulate_at(dirfd, &do_symlink, &cancel_symlink, &args) ;
+}
+
+#endif