]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/replace: add renameat2() replacement
authorStefan Metzmacher <metze@samba.org>
Wed, 7 Aug 2024 11:01:48 +0000 (13:01 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 21 Aug 2024 08:02:30 +0000 (08:02 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15693

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
lib/replace/replace.c
lib/replace/system/filesys.h
lib/replace/wscript

index 0b4e06d8bd53741089f99b646f4be1a7196dc36a..359f43352bd3b8100cc5066b6f4245f1cce17c7f 100644 (file)
@@ -1171,3 +1171,63 @@ long rep_openat2(int dirfd, const char *pathname,
 #endif
 }
 #endif /* !HAVE_OPENAT2 */
+
+#ifndef HAVE_RENAMEAT2
+
+/* fallback to wellknown __NR_renameat2 values */
+#ifndef __NR_renameat2
+# if defined(LINUX) && defined(HAVE_SYS_SYSCALL_H)
+#  if defined(__i386__)
+#   define __NR_renameat2 353
+#  elif defined(__x86_64__) && defined(__LP64__)
+#   define __NR_renameat2 316 /* 316 0x13C */
+#  elif defined(__x86_64__) && defined(__ILP32__)
+#   define __NR_renameat2 1073742140 /* 1073742140 0x4000013C */
+#  elif defined(__aarch64__)
+#   define __NR_renameat2 276
+#  elif defined(__arm__)
+#   define __NR_renameat2 382
+#  elif defined(__sparc__)
+#   define __NR_renameat2 345
+#  endif
+# endif /* defined(LINUX) && defined(HAVE_SYS_SYSCALL_H) */
+#endif /* !__NR_renameat2 */
+
+#ifdef DISABLE_OPATH
+/*
+ * systems without O_PATH also don't have renameat2,
+ * so make sure we at a realistic combination.
+ */
+#undef __NR_renameat2
+#endif /* DISABLE_OPATH */
+
+int rep_renameat2(int __oldfd, const char *__old, int __newfd,
+                 const char *__new, unsigned int __flags)
+{
+       if (__flags != 0) {
+#ifdef __NR_renameat2
+               int ret;
+
+               ret = syscall(__NR_renameat2,
+                             __oldfd,
+                             __old,
+                             __newfd,
+                             __new,
+                             __flags);
+               if (ret != -1 || errno != ENOSYS) {
+                       /*
+                        * if it's ENOSYS, we fallback
+                        * to EINVAL below, otherwise
+                        * we return what the kernel
+                        * did.
+                        */
+                       return ret;
+               }
+#endif
+               errno = EINVAL;
+               return -1;
+       }
+
+       return renameat(__oldfd, __old, __newfd, __new);
+}
+#endif /* ! HAVE_RENAMEAT2 */
index 8005b18780f9f799323319f395318f96f30fd3b3..9738ad52935cd232c714acddaf0f4c6c31ddb6fb 100644 (file)
@@ -278,4 +278,33 @@ long rep_openat2(int dirfd, const char *pathname,
        rep_openat2(dirfd, pathname, how, size)
 #endif /* !HAVE_OPENAT2 */
 
+#ifdef DISABLE_OPATH
+/*
+ * Without O_PATH, the kernel
+ * most likely doesn't have renameat2() too
+ * and we should test the fallback code
+ */
+#undef HAVE_RENAMEAT2
+#endif
+
+#ifndef HAVE_RENAMEAT2
+
+#ifndef RENAME_NOREPLACE
+# define RENAME_NOREPLACE (1 << 0)
+#endif
+
+#ifndef RENAME_EXCHANGE
+# define RENAME_EXCHANGE (1 << 1)
+#endif
+
+#ifndef RENAME_WHITEOUT
+# define RENAME_WHITEOUT (1 << 2)
+#endif
+
+int rep_renameat2(int __oldfd, const char *__old, int __newfd,
+                 const char *__new, unsigned int __flags);
+#define renameat2(__oldfd, __old, __newfd, __new, __flags) \
+       rep_renameat2(__oldfd, __old, __newfd, __new, __flags)
+#endif /* !HAVE_RENAMEAT2 */
+
 #endif
index 77e655bb68b3bf29148bb52af9641dc25f97c716..f5114b69ffc541fc648cb1d5a226d5c028d20f25 100644 (file)
@@ -422,7 +422,7 @@ def configure(conf):
     conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf')
     conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull')
     conf.CHECK_FUNCS('strtouq strtoll __strtoll strtoq memalign posix_memalign')
-    conf.CHECK_FUNCS('fmemopen')
+    conf.CHECK_FUNCS('fmemopen renameat2')
 
     if conf.CONFIG_SET('HAVE_MEMALIGN'):
         conf.CHECK_DECLS('memalign', headers='malloc.h')